home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / Storage / Bento / CMSU.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  78.5 KB  |  2,794 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        CMSU.cpp
  3.  
  4.     Contains:    Implementation CMStorageUnit class.
  5.  
  6.     Owned by:    Vincent Lo
  7.  
  8.     Copyright:    © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <8>     9/26/96    CC        1391203: Changed ClearAllPromises to remove
  13.                                     values that are promised.
  14.                                     1381322: Added private methods
  15.                                     ReleaseAllPromises &
  16.                                     ReleasePromisesFromProperty.
  17.                                     1390741: Release releases promises when
  18.                                     refcount goes to zero.
  19.                                     1391389: ResolveAllPromises does not
  20.                                     preserve the focus
  21.          <7>     9/19/96    DH        Task: low memory changes,1377922,1377888.
  22.                                     Removed some allocations during Purge.
  23.          <6>     8/13/96    DM        1371929: prevent scope id from being
  24.                                     smashed in CloneInto()
  25.          <5>     7/25/96    DH        Fixed NewCMxx methods to check the
  26.                                     somClassReference allocation and throw if
  27.                                     null (No bug #, approved by Bern).
  28.          <4>     5/24/96    jpa        1246074: SOM_CATCH --> SOM_TRY..SOM_ENDTRY
  29.          <2>     3/29/96    DM        1296171: suppress fatal container error in
  30.                                     IsValidStorageUnitRef()
  31.  
  32.     To Do:
  33.     In Progress:
  34.         
  35. */
  36.  
  37. #define CMStorageUnit_Class_Source
  38. #define VARIABLE_MACROS
  39. #include <CMSU.xih>
  40.  
  41. #ifndef SOM_CMStorageUnitRefIterator_xh
  42. #include <CMSURefI.xh>
  43. #endif
  44.  
  45. #ifndef _BENTODEF_
  46. #include "BentoDef.h"
  47. #endif
  48.  
  49. #ifndef SOM_ODStorageUnitCursor_xh
  50. #include <SUCursor.xh>
  51. #endif
  52.  
  53. #ifndef SOM_ODStorageUnitView_xh
  54. #include <SUView.xh>
  55. #endif
  56.  
  57. #ifndef SOM_CMDraft_xh
  58. #include <CMDraft.xh>
  59. #endif
  60.  
  61. #ifndef SOM_CMDocument_xh
  62. #include <CMDoc.xh>
  63. #endif
  64.  
  65. #ifndef SOM_CMCtr_xh
  66. #include <CMCtr.xh>
  67. #endif
  68.  
  69. #ifndef _DRAFPRIV_
  70. #include "DrafPriv.h"
  71. #endif
  72.  
  73. #ifndef __CM_API__
  74. #include "CMAPI.h"
  75. #endif
  76.  
  77. #ifndef _EXCEPT_
  78. #include "Except.h"
  79. #endif
  80.  
  81. #ifndef _AEHSHTBL_
  82. #include "AEHshTbl.h"
  83. #endif
  84.  
  85. #ifndef _ISOSTR_
  86. #include "ISOStr.h"
  87. #endif
  88.  
  89. #ifndef _TEMPOBJ_
  90. #include "TempObj.h"
  91. #endif
  92.  
  93. #ifndef _ODMEMORY_
  94. #include "ODMemory.h"
  95. #endif
  96.  
  97. #ifndef SOM_Module_OpenDoc_StdProps_defined
  98. #include <StdProps.xh>
  99. #endif
  100.  
  101. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  102. #include <StdTypes.xh>
  103. #endif
  104.  
  105. #ifndef SOM_ODStorageSystem_xh
  106. #include <ODStor.xh>
  107. #endif
  108.  
  109. #ifndef SOM_ODSession_xh
  110. #include <ODSessn.xh>
  111. #endif
  112.  
  113. #ifndef _PRMRSLVR_
  114. #include "PrmRslvr.h"
  115. #endif
  116.  
  117. #ifndef _SUREF_
  118. #include "SURef.h"
  119. #endif
  120.  
  121. #ifndef _SUCLONE_
  122. #include "SUClone.h"
  123. #endif
  124.  
  125. #ifndef _STORUTIL_
  126. #include <StorUtil.h>
  127. #endif
  128.  
  129. #ifndef __STDIO__
  130. #include <stdio.h>            // For sprintf
  131. #endif
  132.  
  133. #ifndef _ODDEBUG_
  134. #include "ODDebug.h"
  135. #endif
  136.  
  137. #ifndef _ODNEW_
  138. #include "ODNew.h"
  139. #endif
  140.  
  141. #ifndef _TIME
  142. #include <time.h>
  143. #endif
  144.  
  145. #ifndef _STDTYPIO_
  146. #include <StdTypIO.h>
  147. #endif
  148.  
  149. #ifndef _SESSHDR_
  150. #include "SessHdr.h"
  151. #endif
  152.  
  153. #pragma segment CMStorageUnit
  154.  
  155. #define USE_CLONEHELPER 1
  156.  
  157. //==============================================================================
  158. // Constants
  159. //==============================================================================
  160. #define kInitialHashTableEntries 8
  161. #define kHighBitMask    0x80000000
  162. #define kLowBitsMask    0x7FFFFFFF
  163.  
  164. #if ODDebug
  165. // #define ODDebug_ODStorageUnit 1
  166. #define ODDebug_AddProperty    1
  167. #define ODDebug_AddValue    1
  168. // #define ODDebug_SUCloneHelper    1
  169. #endif
  170.  
  171. //==============================================================================
  172. // Function Prototype
  173. //==============================================================================
  174.  
  175. static ODStorageUnitView* NewODStorageUnitView(ODMemoryHeapID heapID);
  176. static ODStorageUnitCursor* NewODStorageUnitCursor(ODMemoryHeapID heapID);
  177. static CMStorageUnitRefIterator*    NewCMStorageUnitRefIterator(ODMemoryHeapID heapID);
  178.  
  179. #define FailIfInvalidRefCount() ASSERTM(somSelf->GetRefCount(ev) != 0, kODErrZeroRefCount, "Invalid refCount")
  180. #define FailIfIllegalByteArray(value) ASSERT(value != kODNULL, kODErrIllegalNullInput)
  181.  
  182. inline void BREAK_AND_THROW(ODError err)
  183. {
  184. //    Debugger();
  185.     THROW(err);
  186. }
  187.  
  188. #define ODEnterCriticalSection()
  189. #define ODExitCriticalSection()
  190.  
  191. // Callers must call ODSessionMustHaveCMAllocReserve(container);
  192. static ODULong GetPropertySize(CMObject object, CMProperty property);
  193. static ODULong GetObjectSize(CMObject object);
  194.  
  195. //==============================================================================
  196. // CMStorageUnit
  197. //==============================================================================
  198.  
  199. //------------------------------------------------------------------------------
  200. // CMStorageUnit: AcquireDraft
  201. //------------------------------------------------------------------------------
  202.  
  203. SOM_Scope ODDraft*  SOMLINK CMStorageUnitGetDraft(CMStorageUnit *somSelf, Environment *ev)
  204. {
  205.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  206.     CMStorageUnitMethodDebug("CMStorageUnit","GetDraft");
  207.     
  208.     return _fDraft;
  209. }
  210.  
  211. //------------------------------------------------------------------------------
  212. // CMStorageUnit: Acquire
  213. //------------------------------------------------------------------------------
  214.  
  215. SOM_Scope void  SOMLINK CMStorageUnitAcquire(CMStorageUnit *somSelf, Environment *ev)
  216. {
  217.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  218.     CMStorageUnitMethodDebug("CMStorageUnit","Acquire");
  219.  
  220.     SOM_TRY
  221.  
  222.     parent_Acquire(somSelf, ev);
  223.  
  224.     SOM_CATCH_ALL
  225.     SOM_ENDTRY
  226. }
  227.     
  228. //------------------------------------------------------------------------------
  229. // CMStorageUnit: Release
  230. //------------------------------------------------------------------------------
  231.  
  232. SOM_Scope void  SOMLINK CMStorageUnitRelease(CMStorageUnit *somSelf, Environment *ev)
  233. {
  234.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  235.     CMStorageUnitMethodDebug("CMStorageUnit","Release");
  236.  
  237.     SOM_TRY
  238.  
  239.     // Release promised values before refcount is decremented to zero,
  240.     // because some methods throw if refcount is zero
  241.     if (somSelf->GetRefCount(ev) == 1)
  242.         somSelf->ReleaseAllPromises(ev);
  243.  
  244.     CMStorageUnit_parent_ODStorageUnit_Release(somSelf, ev);
  245.     if (somSelf->GetRefCount(ev) == 0) {
  246.         if (_fCurValue != kODNULL) {
  247.             CMContainer cmContainer = _fDraft->GetCMContainer(ev);
  248.             ODSessionMustHaveCMAllocReserve(cmContainer);
  249.             
  250.             CMReleaseValue(_fCurValue);
  251.             
  252.             _fCurValue = kODNULL;
  253.         }
  254.         _fCurProperty = kODNULL;
  255.         _fDraft->ReleaseStorageUnit(ev, _fID);
  256.     }
  257.         
  258.     SOM_CATCH_ALL
  259.     
  260.         ODError err = ErrorCode();
  261.  
  262.         WARN("Error occurred in ODStorageUnit::Release: %d %s", err, ErrorMessage());
  263.  
  264.         if (err == kODErrBentoErr)
  265.             SetErrorCode(kODErrFatalContainerError);
  266.         else if (err != kODErrFatalContainerError)
  267.             SetErrorCode(kODNoError);
  268.             
  269.     SOM_ENDTRY
  270. }
  271.  
  272. //------------------------------------------------------------------------------
  273. // CMStorageUnit: Purge
  274. //------------------------------------------------------------------------------
  275.  
  276. SOM_Scope ODSize SOMLINK CMStorageUnitPurge(CMStorageUnit *somSelf, Environment *ev,
  277.         ODSize size)
  278. {
  279.     // dh -  Took out calls to MustHaveCMAllocReserve because Bento doesn't need
  280.     // 19K to release a value. This was causing major low-mem problems
  281.     // because that's one of the times when this method gets called.
  282.     
  283.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  284.     CMStorageUnitMethodDebug("CMStorageUnit","Purge");
  285.  
  286.     ODULong    runningTotal = 0; ODVolatile( runningTotal );
  287.         
  288.     SOM_TRY
  289.  
  290. // dh - We should make the following code work standalone, and only needed 
  291. // during low memory situations, not during close/save.
  292. //#ifdef bento_actually_frees_memory_with_zero_ref_count
  293.         ODBoolean hasReserve = kODFalse;
  294.         
  295.         if (_fCurValue != kODNULL) {
  296.             CMContainer cmContainer = _fDraft->GetCMContainer(ev);
  297.             hasReserve = kODTrue;
  298.             
  299.             CMReleaseValue(_fCurValue);
  300.             _fCurValue = kODNULL;
  301.         }
  302.         
  303.         _fCurProperty = kODNULL;
  304.         
  305.         if (_fObject != kODNULL) {
  306.         
  307.             IDList*    idList = ((CMDraft*) somSelf->GetDraft(ev))->GetIDList(ev);
  308.             ASSERT(idList != kODNULL, kODErrInvalidIDList);
  309.             
  310.             if (idList->Exists(_fID) == kODFalse) {
  311.                 if ( !hasReserve )
  312.                 {
  313.                     CMContainer cmContainer = _fDraft->GetCMContainer(ev);
  314.                     hasReserve = kODTrue;
  315.                 }
  316.                 CMReleaseObject(_fObject);
  317.                 _fObject = kODNULL;
  318.             }
  319.         } 
  320. //#endif
  321.  
  322.         // dh - call parent Purge method
  323.         runningTotal += parent_Purge(somSelf, ev, size);
  324.         
  325.     SOM_CATCH_ALL
  326.         WARN("Error %ld trying to purge in CMStorageUnitPurge",ErrorCode());
  327.         SetErrorCode(kODNoError);        // dh - Eat the exception; Purge should not 
  328.                                         // propagate it because clients function
  329.                                         // fine whether memory was purged or not.
  330.     SOM_ENDTRY
  331.  
  332.     
  333.     return runningTotal;
  334. }
  335.  
  336. //------------------------------------------------------------------------------
  337. // CMStorageUnit: Exists
  338. //------------------------------------------------------------------------------
  339.  
  340. SOM_Scope ODBoolean     SOMLINK CMStorageUnitExists(CMStorageUnit *somSelf, Environment *ev,
  341.         ODPropertyName propertyName,
  342.                                     ODValueType valueType, 
  343.                                     ODValueIndex valueIndex)
  344. {
  345.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  346.     CMStorageUnitMethodDebug("CMStorageUnit","Exists");
  347.  
  348.     SOM_TRY
  349.  
  350.     CMContainer        container = somSelf->GetCMContainer(ev);
  351.     ODBoolean        propertyFound = kODFalse;
  352.     ODBoolean        valueFound = kODFalse;
  353.     CMProperty        targetProperty;
  354.     CMProperty        property;
  355.     CMType            targetType;
  356.     CMValue            value;
  357.     CMValue            tmpValue;
  358.     ODValueIndex    index;
  359.  
  360.     FailIfInvalidRefCount();
  361.     somSelf->Internalize(ev);
  362.         
  363.     if (_fObject == kODNULL)
  364.         return kODFalse;
  365.  
  366.     ODSessionMustHaveCMAllocReserve(container);
  367.  
  368.     if (propertyName != kODNULL) {
  369.         targetProperty = CMRegisterProperty(container, propertyName);
  370.         if (targetProperty == kODNULL)
  371.             BREAK_AND_THROW(kODErrIllegalPropertyName);
  372.     }
  373.     else
  374.         targetProperty = _fCurProperty;
  375.     
  376.     if (valueType != kODNULL) {
  377.         targetType = CMRegisterType(container, valueType);
  378.         if (targetType == kODNULL)
  379.             BREAK_AND_THROW(kODErrInvalidValueType);
  380.             
  381.         value = CMUseValue(_fObject, targetProperty, targetType);
  382.         if (value != kODNULL) {
  383.             CMReleaseValue(value);
  384.             valueFound = kODTrue;
  385.         }
  386.     }
  387.     else if (valueIndex > 0) {
  388.         index = 1;
  389.         value = CMGetNextValue(_fObject, targetProperty, kODNULL);
  390.         while ((value != kODNULL) && (index < valueIndex)) {
  391.             index++;
  392.             tmpValue = value;
  393.             value = CMGetNextValue(_fObject, targetProperty, tmpValue);
  394.             CMReleaseValue(tmpValue);
  395.         }
  396.         if (value != kODNULL) {
  397.             CMReleaseValue(value);
  398.             if (index == valueIndex)
  399.                 valueFound = kODTrue;
  400.         }
  401.     }
  402.     else {
  403.         if (propertyName != kODNULL) {
  404.             property = CMGetNextObjectProperty(_fObject, kODNULL);
  405.             while ((property != kODNULL) && (valueFound == kODFalse)) {
  406.                 if (targetProperty == property)
  407.                     valueFound = kODTrue;
  408.                 property = CMGetNextObjectProperty(_fObject, property);
  409.             }
  410.         }
  411.         else
  412.             valueFound = kODTrue;
  413.     }
  414.     ODSessionRestoreCMAllocReserve(container);
  415.  
  416.     return    valueFound;
  417.  
  418.     SOM_CATCH_ALL
  419.     SOM_ENDTRY
  420.     return kODFalse;
  421. }
  422.  
  423. //------------------------------------------------------------------------------
  424. // CMStorageUnit: Exists
  425. //------------------------------------------------------------------------------
  426.  
  427. SOM_Scope ODBoolean     SOMLINK CMStorageUnitExistsWithCursor(CMStorageUnit *somSelf, Environment *ev,
  428.         ODStorageUnitCursor* cursor)
  429. {
  430.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  431.     CMStorageUnitMethodDebug("CMStorageUnit","ExistsWithCursor");
  432.  
  433.     SOM_TRY
  434.  
  435.     ODPropertyName propertyName;
  436.     ODValueType    valueType;
  437.     ODValueIndex    valueIndex;
  438.     ODBoolean        exists;
  439.  
  440.     FailIfInvalidRefCount();
  441.     somSelf->Internalize(ev);
  442.     
  443.     cursor->GetProperty(ev, &propertyName);
  444.     cursor->GetValueType(ev, &valueType);
  445.     cursor->GetValueIndex(ev, &valueIndex);
  446.  
  447.     exists = somSelf->Exists(ev, propertyName, valueType, valueIndex);
  448.     
  449.     ODDisposePtr(propertyName);
  450.     ODDisposePtr(valueType);
  451.  
  452.     return exists;
  453.  
  454.     SOM_CATCH_ALL
  455.     SOM_ENDTRY
  456.     return kODFalse;
  457. }
  458.  
  459. //------------------------------------------------------------------------------
  460. // CMStorageUnit: CountProperties
  461. //------------------------------------------------------------------------------
  462.  
  463. SOM_Scope ODULong     SOMLINK CMStorageUnitCountProperties(CMStorageUnit *somSelf, Environment *ev)
  464. {
  465.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  466.     CMStorageUnitMethodDebug("CMStorageUnit","CountProperties");
  467.  
  468.     SOM_TRY
  469.     
  470.     FailIfInvalidRefCount();
  471.     somSelf->Internalize(ev);
  472.  
  473.     CMContainer container = _fDraft->GetCMContainer(ev);
  474.     ODSessionMustHaveCMAllocReserve(container);
  475.     
  476.     return CMCountProperties(_fObject, kODNULL);
  477.  
  478.     SOM_CATCH_ALL
  479.     SOM_ENDTRY
  480.     return 0;
  481. }
  482.  
  483. //------------------------------------------------------------------------------
  484. // CMStorageUnit: CountValues
  485. //------------------------------------------------------------------------------
  486.  
  487. SOM_Scope ODULong     SOMLINK CMStorageUnitCountValues(CMStorageUnit *somSelf, Environment *ev)
  488. {
  489.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  490.     CMStorageUnitMethodDebug("CMStorageUnit","CountValues");
  491.     
  492.     ODULong numValues = 0;
  493.     
  494.     SOM_TRY
  495.     
  496.         FailIfInvalidRefCount();
  497.         somSelf->Internalize(ev);
  498.         
  499.         if (_fCurProperty == kODNULL)
  500.             THROW(kODErrUnfocusedStorageUnit);
  501.     
  502.         CMContainer container = _fDraft->GetCMContainer(ev);
  503.         ODSessionMustHaveCMAllocReserve(container);
  504.         
  505.         numValues = CMCountValues(_fObject, _fCurProperty, kODNULL);
  506.         
  507.     SOM_CATCH_ALL
  508.     SOM_ENDTRY
  509.     
  510.     return numValues;
  511. }
  512.         
  513. //------------------------------------------------------------------------------
  514. // CMStorageUnit: Focus
  515. //------------------------------------------------------------------------------
  516.  
  517. SOM_Scope ODStorageUnit*     SOMLINK CMStorageUnitFocus(CMStorageUnit *somSelf, Environment *ev,
  518.         ODPropertyName propertyName,
  519.                                     ODPositionCode propertyPosCode,
  520.                                     ODValueType valueType,
  521.                                     ODValueIndex valueIndex,
  522.                                     ODPositionCode    valuePosCode)
  523. {
  524.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  525.     CMStorageUnitMethodDebug("CMStorageUnit","Focus");
  526.  
  527.     SOM_TRY
  528.     
  529.     FailIfInvalidRefCount();
  530.     somSelf->Internalize(ev);
  531.     
  532.     CMProperty    property = _fCurProperty;
  533.     CMValue        value = _fCurValue;
  534.     
  535.     CMContainer container = _fDraft->GetCMContainer(ev);
  536.     ODSessionMustHaveCMAllocReserve(container);
  537.     
  538.     if (propertyName != kODNULL) {
  539.         property = CMRegisterProperty(container, propertyName);
  540.         if (property == kODNULL) {
  541. #ifdef ODDebug_ODStorageUnit
  542.     somPrintf("Error in Focus: ID %x PID %x propertyName %s\n", somSelf->GetID(ev), _fObjectID, propertyName);
  543. #endif
  544.             somSelf->CleanupAndFail(ev, kODErrIllegalPropertyName);
  545.         }
  546.     }
  547.     else {
  548.         _fHasPropertyLooped = propertyPosCode & kODPosMWrap;
  549.         switch (propertyPosCode) {
  550.             case kODPosUndefined:
  551.                 somSelf->CleanupAndFail(ev, kODErrUnsupportedPosCode);
  552.                 break;
  553.             case kODPosSame:
  554.                 break;
  555.             case kODPosAll:
  556.                 property = kODNULL;
  557.                 break;
  558.             case kODPosFirstSib:
  559.                 property = CMGetNextObjectProperty(_fObject, kODNULL);
  560.                 if (property == kODNULL)
  561.                     somSelf->CleanupAndFail(ev, kODErrPropertyDoesNotExist);
  562.                 break;
  563.             case kODPosLastSib:
  564.                 property = CMGetPrevObjectProperty(_fObject, kODNULL);
  565.                 if (property == kODNULL)
  566.                     somSelf->CleanupAndFail(ev, kODErrPropertyDoesNotExist);
  567.                 break;
  568.             case kODPosNextSib:
  569.                 property = CMGetNextObjectProperty(_fObject, property);
  570.                 if (property == kODNULL)
  571.                     somSelf->CleanupAndFail(ev, kODErrPropertyDoesNotExist);
  572.                 break;
  573.             case kODPosPrevSib:
  574.                 property = CMGetPrevObjectProperty(_fObject, property);
  575.                 if (property == kODNULL)
  576.                     somSelf->CleanupAndFail(ev, kODErrPropertyDoesNotExist);
  577.                 break;
  578.             case kODPosFirstBelow:
  579.             case kODPosLastBelow:
  580.             case kODPosFirstAbove:
  581.             case kODPosLastAbove:
  582.             default:
  583.                 somSelf->CleanupAndFail(ev, kODErrUnsupportedPosCode);
  584.                 break;
  585.         }
  586.     }
  587.     
  588.     ODBoolean needReleaseValue = kODTrue;
  589.  
  590.     if (valueType != kODNULL) {
  591.         CMType type = kODNULL;
  592.         
  593.         CMType targetType = CMRegisterType(container, valueType);
  594.         
  595.         value = CMUseValue(_fObject, property, targetType);
  596.         if (value == kODNULL)
  597.             somSelf->CleanupAndFail(ev, kODErrSUValueDoesNotExist);
  598.             
  599.     } else if (valueIndex > 0) {
  600.         ODULong        i = 1;
  601.         CMValue        tmpValue;
  602.  
  603.         value = CMGetNextValue(_fObject, property, kODNULL);
  604.         while ((value != kODNULL) && (i < valueIndex)) {
  605.             tmpValue = value;
  606.             value = CMGetNextValue(_fObject, property, tmpValue);
  607.             CMReleaseValue(tmpValue);
  608.             i++;
  609.         }        
  610.         if (value == kODNULL)
  611.             somSelf->CleanupAndFail(ev, kODErrValueIndexOutOfRange);
  612.     }
  613.     else {
  614.         _fHasValueLooped = valuePosCode & kODPosMWrap;
  615.         switch (valuePosCode) {
  616.             case kODPosUndefined:
  617.                 value = kODNULL;
  618.             break;
  619.             case kODPosAll:
  620.                 value = kODNULL;
  621.                 break;
  622.             case kODPosFirstSib:
  623.                 value = CMGetNextValue(_fObject, property, kODNULL);
  624.                 if (value == kODNULL)
  625.                     somSelf->CleanupAndFail(ev, kODErrSUValueDoesNotExist);
  626.                 break;
  627.             case kODPosNextSib:
  628.                 value = CMGetNextValue(_fObject, property, value);
  629.                 if (value == kODNULL)
  630.                     somSelf->CleanupAndFail(ev, kODErrSUValueDoesNotExist);
  631.                 break;
  632.             case kODPosSame:
  633.                 needReleaseValue = kODFalse;
  634.                 break;
  635.             case kODPosLastSib:
  636.                 value = CMGetPrevValue(_fObject, property, kODNULL);
  637.                 if (value == kODNULL)
  638.                     somSelf->CleanupAndFail(ev, kODErrSUValueDoesNotExist);
  639.                 break;
  640.             case kODPosPrevSib:
  641.                 value = CMGetPrevValue(_fObject, property, value);
  642.                 if (value == kODNULL)
  643.                     somSelf->CleanupAndFail(ev, kODErrSUValueDoesNotExist);
  644.                 break;
  645.             case kODPosFirstBelow:
  646.             case kODPosLastBelow:
  647.             case kODPosFirstAbove:
  648.             case kODPosLastAbove:
  649.             default:
  650.                 somSelf->CleanupAndFail(ev, kODErrUnsupportedPosCode);
  651.                 break;
  652.         }
  653.     }
  654.     
  655.     if (needReleaseValue != kODFalse) 
  656.         if (_fCurValue != kODNULL)
  657.             CMReleaseValue(_fCurValue);
  658.     
  659.     _fOffset = 0;
  660.     _fCurValue = value;
  661.     _fCurProperty = property;
  662.  
  663.     ODSessionRestoreCMAllocReserve(container);
  664.     
  665.     return somSelf;
  666.  
  667.     SOM_CATCH_ALL
  668.     SOM_ENDTRY
  669.     return somSelf;
  670. }
  671.  
  672. //------------------------------------------------------------------------------
  673. // CMStorageUnit: Focus
  674. //------------------------------------------------------------------------------
  675.  
  676. SOM_Scope ODStorageUnit*     SOMLINK CMStorageUnitFocusWithCursor(CMStorageUnit *somSelf, Environment *ev,
  677.         ODStorageUnitCursor* suCursor)
  678. {
  679.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  680.     CMStorageUnitMethodDebug("CMStorageUnit","FocusWithCursor");
  681.     
  682.     SOM_TRY
  683.     
  684.     ODPropertyName    propertyName;
  685.     ODValueType    valueType;
  686.     ODValueIndex    valueIndex;
  687.     
  688.     FailIfInvalidRefCount();
  689.     somSelf->Internalize(ev);
  690.  
  691.     if (suCursor == kODNULL)
  692.         BREAK_AND_THROW(kODErrIllegalNullSUCursorInput);
  693.  
  694.     suCursor->GetProperty(ev, &propertyName);
  695.     suCursor->GetValueType(ev, &valueType);
  696.     suCursor->GetValueIndex(ev, &valueIndex);
  697.     
  698.     somSelf->Focus(ev, propertyName,
  699.                 kODPosAll,
  700.                 valueType,
  701.                 valueIndex,
  702.                 kODPosAll);
  703.                 
  704.     if (propertyName != kODNULL)
  705.         ODDisposePtr(propertyName);
  706.         
  707.     if (valueType != kODNULL)
  708.         ODDisposePtr(valueType);
  709.     
  710.     return somSelf;
  711.  
  712.     SOM_CATCH_ALL
  713.     SOM_ENDTRY
  714.     return somSelf;
  715. }
  716.  
  717. //------------------------------------------------------------------------------
  718. // CMStorageUnit: Externalize
  719. //------------------------------------------------------------------------------
  720.  
  721. SOM_Scope ODStorageUnit*     SOMLINK CMStorageUnitExternalize(CMStorageUnit *somSelf, Environment *ev)
  722. {
  723.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  724.     CMStorageUnitMethodDebug("CMStorageUnit","Externalize");
  725.  
  726.     SOM_TRY
  727.  
  728.     PreserveFocus    originalFocus(ev, somSelf);
  729.  
  730.     if (_fDirty) {    
  731.         somSelf->ResolveAllPromises(ev);
  732.     
  733.         if (_fSURefKeeper != kODNULL)
  734.             _fSURefKeeper->Externalize();
  735.         
  736.         if (somSelf->Exists(ev, kODPropModDate, kODTime_T, 0)) {
  737.             ODSetTime_TProp(ev, somSelf, kODPropModDate, kODTime_T, (ODTime) _fModificationDate);
  738.         }
  739.         
  740.         _fDirty = kODFalse;
  741.     }
  742.     return somSelf;
  743.  
  744.     SOM_CATCH_ALL
  745.     SOM_ENDTRY
  746.     return somSelf;
  747. }
  748.  
  749. //------------------------------------------------------------------------------
  750. // CMStorageUnit: Internalize
  751. //------------------------------------------------------------------------------
  752.  
  753. SOM_Scope ODStorageUnit*     SOMLINK CMStorageUnitInternalize(CMStorageUnit *somSelf, Environment *ev)
  754. {
  755.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  756.     CMStorageUnitMethodDebug("CMStorageUnit","Internalize");
  757.  
  758.     SOM_TRY
  759.         
  760.     if (_fObject == kODNULL) {
  761.  
  762.         IDList*    idList = ((CMDraft*) somSelf->GetDraft(ev))->GetIDList(ev);
  763.         ASSERT(idList != kODNULL, kODErrInvalidIDList);
  764.                 
  765.         if (idList->Exists(_fID) != kODFalse) {            
  766.             _fObject = (CMObject) idList->Get(_fID);
  767.         }
  768.         else if (_fObjectID != kODNULL) {
  769.             CMContainer container = _fDraft->GetCMContainer(ev);
  770.             ODSessionMustHaveCMAllocReserve(container);
  771.             
  772.             _fObject = CMGetObject(container, _fObjectID);
  773.  
  774.             ODSessionRestoreCMAllocReserve(container);
  775.             
  776. //            if (_fObject == kODNULL)
  777. //                BREAK_AND_THROW(kODErrBentoCannotNewObject);
  778.             if (_fObject != kODNULL)
  779.                 idList->Add(_fID, _fObject);
  780.         }
  781.         else
  782.             BREAK_AND_THROW(kODErrInvalidStorageUnit);
  783.     }
  784.         
  785.     return somSelf;
  786.  
  787.     SOM_CATCH_ALL
  788.     SOM_ENDTRY
  789.     return somSelf;
  790. }
  791.  
  792. //------------------------------------------------------------------------------
  793. // CMStorageUnit: GetID
  794. //------------------------------------------------------------------------------
  795.  
  796. SOM_Scope ODStorageUnitID  SOMLINK CMStorageUnitGetID(CMStorageUnit *somSelf, Environment *ev)
  797. {
  798.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  799.     CMStorageUnitMethodDebug("CMStorageUnit","GetID");
  800.  
  801.     // Do not call fail if RefCount is zero because GetID can be called
  802.     // from Remove where RefCount MUST be zero -pjh
  803.     // FailIfInvalidRefCount();
  804.     
  805.     return _fID;
  806. }
  807.  
  808. //------------------------------------------------------------------------------
  809. // CMStorageUnit: GetName
  810. //------------------------------------------------------------------------------
  811.  
  812. SOM_Scope ODStorageUnitName  SOMLINK CMStorageUnitGetName(CMStorageUnit *somSelf, Environment *ev)
  813. {
  814.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  815.     CMStorageUnitMethodDebug("CMStorageUnit","GetName");
  816.     
  817.     SOM_TRY
  818.     
  819.     FailIfInvalidRefCount();
  820.     return ODGetISOStrProp(ev, somSelf, kODPropStorageUnitName, kODISOStr, kODNULL, kODNULL);
  821.  
  822.     SOM_CATCH_ALL
  823.     SOM_ENDTRY
  824.     return kODNULL;
  825. }
  826.     
  827. //------------------------------------------------------------------------------
  828. // CMStorageUnit: SetName
  829. //------------------------------------------------------------------------------
  830.  
  831. SOM_Scope void  SOMLINK CMStorageUnitSetName(CMStorageUnit *somSelf, Environment *ev,
  832.         ODStorageUnitName name)
  833. {
  834.     // CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  835.     CMStorageUnitMethodDebug("CMStorageUnit","SetName");
  836.  
  837.     SOM_TRY
  838.             
  839.     FailIfInvalidRefCount();
  840.         
  841.     ODSetISOStrProp(ev, somSelf, kODPropStorageUnitName, kODISOStr, name);
  842.  
  843.     SOM_CATCH_ALL
  844.     SOM_ENDTRY
  845. }
  846.  
  847. //------------------------------------------------------------------------------
  848. // CMStorageUnit: AddProperty
  849. //------------------------------------------------------------------------------
  850.  
  851. SOM_Scope ODStorageUnit*     SOMLINK CMStorageUnitAddProperty(CMStorageUnit *somSelf, Environment *ev,
  852.         ODPropertyName propertyName)    
  853. {
  854.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  855.     CMStorageUnitMethodDebug("CMStorageUnit","AddProperty");
  856.  
  857.     SOM_TRY
  858.  
  859. #ifdef ODDebug_ODStorageUnit
  860.     somPrintf("AddProperty %x %x %s\n", _fID, _fObjectID, propertyName);
  861. #endif
  862.     
  863.     CMContainer container = somSelf->GetCMContainer(ev);    
  864.     CMProperty    property = kODNULL;
  865.     
  866.     FailIfInvalidRefCount();
  867.     
  868.     somSelf->Internalize(ev);
  869.     
  870.     if (propertyName == kODNULL)
  871.         BREAK_AND_THROW(kODErrIllegalNullPropertyInput);
  872.     if (propertyName != kODNULL) {
  873.  
  874.         ODSessionMustHaveCMAllocReserve(container);
  875.         
  876.         property = CMRegisterProperty(container,propertyName);
  877.         if (property == kODNULL) {
  878.             somSelf->CleanupAndFail(ev, kODErrCannotAddProperty);
  879.         }
  880.         else {
  881.         
  882. #if ODDebug_AddProperty
  883.             CMProperty tmpProp = kODNULL;
  884.             do {
  885.                 ODSessionMustHaveCMAllocReserve(container); // safest once per loop
  886.                 tmpProp = CMGetNextObjectProperty(_fObject, tmpProp);
  887.             } while ((tmpProp != kODNULL) && (tmpProp != property));
  888.             
  889.             if (tmpProp == property) {
  890.                 WARN("Property exists already.");
  891.                 somPrintf("propertyName %s exists already.\n", propertyName);
  892.             }
  893. #endif
  894.  
  895.             if (_fCurValue != kODNULL) {
  896.                 CMReleaseValue(_fCurValue);
  897.                 _fCurValue = kODIDAll;
  898.             }
  899.             _fCurProperty = property;
  900.             somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  901.         }
  902.         ODSessionRestoreCMAllocReserve(container);
  903.     }
  904.     return somSelf;
  905.  
  906.     SOM_CATCH_ALL
  907.     SOM_ENDTRY
  908.     return somSelf;
  909. }
  910.  
  911.     
  912. //------------------------------------------------------------------------------
  913. // CMStorageUnit: AddValue
  914. //------------------------------------------------------------------------------
  915.  
  916. SOM_Scope ODStorageUnit*  SOMLINK CMStorageUnitAddValue(CMStorageUnit *somSelf, Environment *ev,
  917.         ODValueType type)
  918. {
  919.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  920.     CMStorageUnitMethodDebug("CMStorageUnit","AddValue");
  921.  
  922.     SOM_TRY
  923.  
  924.     CMContainer    container = somSelf->GetCMContainer(ev);
  925.     char*        dummyBuffer = "";
  926.     CMValue        value;
  927.     
  928.     FailIfInvalidRefCount();
  929.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  930.     
  931.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL))
  932.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  933.     if (type == kODNULL)
  934.         BREAK_AND_THROW(kODErrIllegalNullValueTypeInput);
  935.     else {
  936.         ODSessionMustHaveCMAllocReserve(container);
  937.  
  938.         _fCurType = CMRegisterType(container, type);
  939.         if (_fCurType == kODNULL)
  940.             BREAK_AND_THROW(kODErrInvalidValueType);
  941.         value = CMUseValue(_fObject, _fCurProperty, _fCurType);
  942.         if (value == kODNULL) {
  943.             value = CMNewValue(_fObject, _fCurProperty, _fCurType);
  944.             if (value == kODNULL)
  945.                 somSelf->CleanupAndFail(ev, kODErrBentoCannotNewValue);
  946.             CMWriteValueData(value, dummyBuffer, 0, 0);
  947.         }
  948. #if ODDebug_AddValue
  949.         else {
  950.             WARN("Value exists already.");
  951.             CMGlobalName propName = CMGetGlobalName(_fCurProperty);
  952.             somPrintf("Property %s Value %s exists already.\n", propName, type);
  953.         }
  954. #endif
  955.         if (_fCurValue != kODNULL)
  956.             CMReleaseValue(_fCurValue);
  957.         _fCurValue = value;
  958.         _fOffset = 0;
  959.  
  960.         ODSessionRestoreCMAllocReserve(container);
  961.     }
  962.     return somSelf;
  963.  
  964.     SOM_CATCH_ALL
  965.     SOM_ENDTRY
  966.     return somSelf;
  967. }
  968.  
  969. //------------------------------------------------------------------------------
  970. // CMStorageUnit: Remove
  971. //------------------------------------------------------------------------------
  972.  
  973. SOM_Scope ODStorageUnit*     SOMLINK CMStorageUnitRemove(CMStorageUnit *somSelf, Environment *ev)
  974. {
  975.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  976.     CMStorageUnitMethodDebug("CMStorageUnit","Remove");
  977.  
  978.     SOM_TRY
  979.  
  980.     FailIfInvalidRefCount();
  981.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  982.  
  983.     CMContainer container = _fDraft->GetCMContainer(ev);
  984.     ODSessionMustHaveCMAllocReserve(container);
  985.  
  986.     if (_fCurValue != kODNULL) {
  987.         if ((_fPromiseResolver != kODNULL) && (_fPromiseResolver->IsSettingPromise() == kODFalse))
  988.             _fPromiseResolver->ClearPromise(ev);
  989.         CMDeleteValue(_fCurValue);
  990.         _fCurValue = kODNULL;
  991.     }
  992.     else if (_fCurProperty != kODNULL) {
  993.         somSelf->ReleasePromisesInProperty(ev);
  994.         CMDeleteObjectProperty(_fObject, _fCurProperty);
  995.         _fCurProperty = kODNULL;
  996.     }
  997.     else {
  998.         somSelf->ReleaseAllPromises(ev);
  999.         CMProperty curProperty = CMGetNextObjectProperty(_fObject, kODNULL);
  1000.         while (curProperty != kODNULL) {
  1001.             CMGlobalName name = CMGetGlobalName(curProperty);
  1002.             CMProperty property = curProperty;
  1003.             curProperty = CMGetNextObjectProperty(_fObject, curProperty);
  1004.             if (ODISOStrNCompare(name, kODBentoPrefix, ODISOStrLength(kODBentoPrefix)) != 0) {
  1005.                 CMDeleteObjectProperty(_fObject, property);
  1006.             }
  1007.         }
  1008.     }
  1009.     ODSessionRestoreCMAllocReserve(container);
  1010.     
  1011.     return somSelf;
  1012.  
  1013.     SOM_CATCH_ALL
  1014.     SOM_ENDTRY
  1015.     return somSelf;
  1016. }
  1017.  
  1018. //------------------------------------------------------------------------------
  1019. // CMStorageUnit: CloneInto
  1020. //------------------------------------------------------------------------------
  1021.  
  1022. SOM_Scope void  SOMLINK CMStorageUnitCloneInto(CMStorageUnit *somSelf, Environment *ev,
  1023.         ODDraftKey key, ODStorageUnit* toSU, ODID scopeID)
  1024. {
  1025.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1026.     CMStorageUnitMethodDebug("CMStorageUnit","CloneInto");
  1027.  
  1028.     SOM_TRY
  1029.  
  1030. #ifdef USE_CLONEHELPER
  1031.     if (_fSUCloneHelper->ShouldClone(key, scopeID) != kODFalse) {
  1032. #endif
  1033. #ifdef ODDebug_SUCloneHelper
  1034.         somPrintf("Cloning %d in scope %d\n", somSelf->GetID(ev), scopeID);
  1035. #endif
  1036.  
  1037. #ifdef ODDebug_ODStorageUnit
  1038.     somPrintf("CMSU CloneInto: from %x %x to %x %x scope %x\n",
  1039.         _fID, _fObjectID, toSU->GetID(ev), ((CMStorageUnit*) toSU)->GetObjectID(ev), scopeID);
  1040. #endif
  1041.     
  1042.     if (((CMDraft*) somSelf->GetDraft(ev))->IsValidDraftKey(ev, key) == kODFalse)
  1043.         THROW(kODErrInvalidDraftKey);
  1044.  
  1045.     FailIfInvalidRefCount();
  1046.         
  1047.     ODULong            numProperties;
  1048.     ODULong            numValues;
  1049.     ODULong            i;
  1050.     ODULong            j;
  1051.     ODPropertyName    propertyName;
  1052.     CMGlobalName    typeName;
  1053.     ODULong            tmpSize;
  1054.     ODULong            size;
  1055.     ODPtr            buffer;
  1056.     ODStorageUnitCursor*    originalFocus = kODNULL;
  1057.     
  1058.     somSelf->Internalize(ev);
  1059.  
  1060.     if (_fCurProperty != kODNULL)
  1061.         originalFocus = somSelf->CreateCursorWithFocus(ev);
  1062.         
  1063.     somSelf->Focus(ev, (ODPropertyName) kODNULL, 
  1064.                             kODPosAll,
  1065.                             kODTypeAll,
  1066.                             0,
  1067.                             kODPosUndefined);
  1068.                             
  1069.     numProperties = somSelf->CountProperties(ev);
  1070.     
  1071.     for (i = 0; i < numProperties; i++) {
  1072.     
  1073.         somSelf->Focus(ev, (ODPropertyName) kODNULL,
  1074.                         kODPosNextSib,
  1075.                         kODTypeAll,
  1076.                         0,
  1077.                         kODPosUndefined);
  1078.     
  1079.         propertyName = somSelf->GetProperty(ev);
  1080.         
  1081. #if ODDebug_AddProperty
  1082.         if (toSU->Exists(ev, propertyName, kODNULL, 0) != kODFalse) {
  1083.             toSU->Focus(ev, propertyName, kODPosUndefined, kODNULL, 0, kODPosUndefined);
  1084.         }
  1085.         else
  1086.             toSU->AddProperty(ev, propertyName);
  1087. #else
  1088.         toSU->AddProperty(ev, propertyName);
  1089. #endif
  1090.     
  1091.         numValues = somSelf->CountValues(ev);    
  1092.         
  1093.         for (j = 0; j < numValues; j++) {
  1094.  
  1095.             somSelf->Focus(ev, (ODPropertyName) kODNULL,
  1096.                             kODPosSame,
  1097.                             kODNULL,
  1098.                             0,
  1099.                             kODPosNextSib);
  1100.  
  1101.             typeName = somSelf->GetType(ev);
  1102.             
  1103.             // Do no overrite existing values except for the storage unit type property.
  1104.             // New storage units are created with a generic storage unit type which should
  1105.             // be overwritten.  The link iterators currently use the storage unit type
  1106.             // property to identify link and linkSource storage units.
  1107.             if ((ODISOStrCompare(propertyName, (const ODISOStr) kODPropStorageUnitType) == 0)
  1108.                 || (toSU->Exists(ev, propertyName, typeName, 0) == kODFalse)) { 
  1109.  
  1110. #ifdef ODDebug_ODStorageUnit            
  1111.                 somPrintf("Copying from %x %x %s %s to %x %x\n", 
  1112.                     _fID, _fObjectID, propertyName, typeName, toSU->GetID(ev), ((CMStorageUnit*) toSU)->GetObjectID(ev));
  1113. #endif
  1114.  
  1115. #if ODDebug_AddValue
  1116.                 if (toSU->Exists(ev, propertyName, typeName, 0) != kODFalse) {
  1117.                     toSU->Focus(ev, propertyName, kODPosUndefined, typeName, 0, kODPosUndefined);
  1118.                 }
  1119.                 else
  1120.                     toSU->AddValue(ev, typeName);
  1121. #else                
  1122.                 toSU->AddValue(ev, typeName);
  1123. #endif
  1124.                 
  1125.                 tmpSize = toSU->GetSize(ev);
  1126.                 toSU->DeleteValue(ev, tmpSize);
  1127.                 
  1128.                 PreserveFocus* focus = new PreserveFocus(ev, somSelf);
  1129.                 size = somSelf->GetSize(ev);
  1130.                 delete focus;
  1131.                 numValues = somSelf->CountValues(ev);
  1132.                 numProperties = somSelf->CountProperties(ev);
  1133.                 
  1134.                 buffer = ODNewPtr(size, somSelf->GetHeap(ev));
  1135.                 StorageUnitGetValue(somSelf, ev, size, (ODValue) buffer);
  1136.                 StorageUnitSetValue(toSU, ev, size, (ODValue) buffer);
  1137.                 ODDisposePtr(buffer);
  1138.             }
  1139.             else {
  1140.                 toSU->Focus(ev, propertyName,
  1141.                             kODPosUndefined,
  1142.                             typeName,
  1143.                             0,
  1144.                             kODPosUndefined);
  1145.             }
  1146.             
  1147.             ODStorageUnitRefIterator*    iter;
  1148.             ODStorageUnitRef            ref;
  1149.  
  1150.             iter = somSelf->CreateStorageUnitRefIterator(ev);                
  1151.                 for(iter->First(ev, ref); iter->IsNotComplete(ev) != kODFalse; iter->Next(ev, ref)) {
  1152.                 if (somSelf->IsValidStorageUnitRef(ev, ref) != kODFalse) {                
  1153.                     ODStorageUnitID            toEmbeddedID = 0;
  1154.                     ODStorageUnitID            containingFrameID = 0;
  1155.                     ODBoolean                strongClone = somSelf->IsStrongStorageUnitRef(ev, ref);
  1156.                     ODStorageUnitID            fromEmbeddedID = somSelf->GetIDFromStorageUnitRef(ev, ref);
  1157.     
  1158.                     // Do *not* change the value of scopeID, because this will
  1159.                     // interfere with the cloning of subsequent values and
  1160.                     // properties. (1371928)
  1161.                     
  1162.                     ODID subScopeID = scopeID; // possible new scope
  1163.                     if (subScopeID != 0) {
  1164.                         TempODStorageUnit fromEmbeddedSU = _fDraft->AcquireStorageUnit(ev, fromEmbeddedID);
  1165.                         if ((containingFrameID = ODGetWeakSURefProp(ev, fromEmbeddedSU, kODPropContainingFrame, kODWeakStorageUnitRef))
  1166.                             != kODNULLID)
  1167.                         {                                
  1168.                             if (containingFrameID == subScopeID)
  1169.                                 subScopeID = fromEmbeddedID;
  1170.                             else
  1171.                                 strongClone = kODFalse;
  1172.                         }
  1173.                     }
  1174.                     
  1175.                     if (strongClone != kODFalse) {
  1176. #ifdef ODDebug_ODStorageUnit
  1177.                         somPrintf("{{{ Strong Clone %x Begins\n", fromEmbeddedID);
  1178. #endif
  1179.                             toEmbeddedID = _fDraft->Clone(ev, key, fromEmbeddedID, 0, subScopeID);
  1180. #ifdef ODDebug_ODStorageUnit
  1181.                         somPrintf("}}} Strong Clone %x Ends %x\n", fromEmbeddedID, toEmbeddedID);
  1182. #endif
  1183.                     }
  1184.                     else {
  1185. #ifdef ODDebug_ODStorageUnit
  1186.                         somPrintf("Begin Weak Clone from %x\n", fromEmbeddedID);
  1187. #endif
  1188.                             toEmbeddedID = _fDraft->WeakClone(ev, key, fromEmbeddedID, 0, subScopeID);
  1189. #ifdef ODDebug_ODStorageUnit
  1190.                         somPrintf("End Weak Clone from %x %x to %x %x\n", fromEmbeddedID, toEmbeddedID);
  1191. #endif
  1192.                     }
  1193.                     if (toEmbeddedID != 0) {
  1194.     
  1195. #ifdef ODDebug_ODStorageUnit
  1196.     ODPropertyName    tmpPropertyName = somSelf->GetProperty(ev);
  1197.     ODValueType    tmpTypeName = somSelf->GetType(ev);
  1198.     ODPropertyName    tmpToPropertyName = toSU->GetProperty(ev);
  1199.     ODValueType    tmpToTypeName = toSU->GetType(ev);
  1200.     somPrintf("SetStorageUnitRef: FromID %x %s %s to toID %x %s %s\n",
  1201.                                                 fromEmbeddedID,
  1202.                                                 tmpPropertyName,
  1203.                                                 tmpTypeName,
  1204.                                                 toEmbeddedID,
  1205.                                                 tmpToPropertyName,
  1206.                                                 tmpToTypeName);
  1207.     ODDisposePtr(tmpPropertyName);
  1208.     ODDisposePtr(tmpTypeName);
  1209.     ODDisposePtr(tmpToPropertyName);
  1210.     ODDisposePtr(tmpToTypeName);
  1211. #endif
  1212.     
  1213.                         toSU->SetStorageUnitRef(ev, toEmbeddedID, ref);
  1214.                     }
  1215.                 }
  1216.             }
  1217.             delete iter;
  1218.  
  1219.             ODDisposePtr(typeName);
  1220.         }
  1221.         ODDisposePtr(propertyName);
  1222.     }
  1223.     
  1224.     if (originalFocus == kODNULL)
  1225.         somSelf->Focus(ev, kODNULL, kODPosAll, kODNULL, 0, kODPosAll);
  1226.     else {
  1227.         somSelf->FocusWithCursor(ev, originalFocus);
  1228.         delete originalFocus;
  1229.     }
  1230. #ifdef USE_CLONEHELPER
  1231.     }
  1232. #endif
  1233. #ifdef USE_CLONEHELPER
  1234. #ifdef ODDebug_SUCloneHelper
  1235.     else
  1236.         somPrintf("Not cloning %d in scope %d\n", somSelf->GetID(ev), scopeID);
  1237. #endif
  1238. #endif
  1239.  
  1240.     SOM_CATCH_ALL
  1241.     SOM_ENDTRY
  1242. }
  1243.  
  1244. //------------------------------------------------------------------------------
  1245. // CMStorageUnit: CreateView
  1246. //------------------------------------------------------------------------------
  1247.  
  1248. SOM_Scope ODStorageUnitView*     SOMLINK CMStorageUnitCreateView(CMStorageUnit *somSelf, Environment *ev)
  1249. {
  1250.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1251.     CMStorageUnitMethodDebug("CMStorageUnit","CreateView");
  1252.     
  1253.     SOM_TRY
  1254.  
  1255.     ODStorageUnitView* suView = kODNULL;
  1256.  
  1257.     FailIfInvalidRefCount();
  1258.     
  1259.     ODStorageUnitCursor* cursor = somSelf->CreateCursorWithFocus(ev);
  1260.     
  1261.     suView = NewODStorageUnitView(somSelf->GetHeap(ev));
  1262.     suView->InitStorageUnitView(ev, somSelf, cursor);
  1263.  
  1264.     return suView;
  1265.  
  1266.     SOM_CATCH_ALL
  1267.     SOM_ENDTRY
  1268.     return kODNULL;
  1269. }
  1270.  
  1271. //------------------------------------------------------------------------------
  1272. // CMStorageUnit: CreateCursor
  1273. //------------------------------------------------------------------------------
  1274.  
  1275. SOM_Scope ODStorageUnitCursor*  SOMLINK CMStorageUnitCreateCursor(CMStorageUnit *somSelf, Environment *ev,
  1276.         ODPropertyName propertyName,
  1277.         ODValueType valueType,
  1278.         ODValueIndex valueIndex)
  1279. {
  1280.     /*    CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf); */
  1281.     CMStorageUnitMethodDebug("CMStorageUnit","CMStorageUnitCreateCursor");
  1282.     
  1283.     SOM_TRY
  1284.     
  1285.     ODStorageUnitCursor*    suCursor = NewODStorageUnitCursor(somSelf->GetHeap(ev));
  1286.     suCursor->InitStorageUnitCursor(ev, propertyName, valueType, valueIndex);
  1287.     
  1288.     return suCursor;
  1289.  
  1290.     SOM_CATCH_ALL
  1291.     SOM_ENDTRY
  1292.     return kODNULL;
  1293. }
  1294.  
  1295. //------------------------------------------------------------------------------
  1296. // CMStorageUnit: CreateCursorWithFocus
  1297. //------------------------------------------------------------------------------
  1298.  
  1299. SOM_Scope ODStorageUnitCursor*  SOMLINK CMStorageUnitCreateCursorWithFocus(CMStorageUnit *somSelf, Environment *ev)
  1300. {
  1301.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1302.     CMStorageUnitMethodDebug("CMStorageUnit","CreateCursorWithFocus");
  1303.  
  1304.     SOM_TRY
  1305.  
  1306.     ODStorageUnitCursor*     suCursor = kODNULL;
  1307.     ODPropertyName            propertyName = kODNULL;
  1308.     ODValueType            valueType = kODNULL;
  1309.  
  1310.     FailIfInvalidRefCount();
  1311.     somSelf->Internalize(ev);
  1312.  
  1313.     if (_fCurProperty != kODNULL)
  1314.         propertyName = somSelf->GetProperty(ev);
  1315.     
  1316.     if (_fCurValue != kODNULL)
  1317.         valueType = somSelf->GetType(ev);
  1318.  
  1319.     suCursor = NewODStorageUnitCursor(somSelf->GetHeap(ev));
  1320.     suCursor->InitStorageUnitCursor(ev, propertyName, valueType, _fCurValueIndex);
  1321.     
  1322.     ODDisposePtr(propertyName);
  1323.     ODDisposePtr(valueType);
  1324.                         
  1325.     return suCursor;
  1326.  
  1327.     SOM_CATCH_ALL
  1328.     SOM_ENDTRY
  1329.     return kODNULL;
  1330. }
  1331.  
  1332. //------------------------------------------------------------------------------
  1333. // CMStorageUnit: GetProperty
  1334. //------------------------------------------------------------------------------
  1335.  
  1336. SOM_Scope ODPropertyName  SOMLINK CMStorageUnitGetProperty(CMStorageUnit *somSelf, Environment *ev)
  1337. {
  1338.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1339.     CMStorageUnitMethodDebug("CMStorageUnit","GetProperty");
  1340.  
  1341.     SOM_TRY
  1342.     
  1343.     CMGlobalName    tmp;
  1344.     ODPropertyName    propertyName = kODNULL;
  1345.  
  1346.     FailIfInvalidRefCount();
  1347.  
  1348.     if (_fCurProperty == kODNULL)
  1349.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1350.     
  1351.     // CMContainer container = _fDraft->GetCMContainer(ev);
  1352.     // ODSessionMustHaveCMAllocReserve(container);
  1353.     // CMIsProperty() and CMGetGlobalName() do not allocate memory.
  1354.  
  1355.     if (CMIsProperty(_fCurProperty)) {
  1356.         tmp = CMGetGlobalName(_fCurProperty);
  1357.         propertyName = ODISOStrFromCStr(tmp);
  1358.     }
  1359.     // ODSessionRestoreCMAllocReserve(container);
  1360.     
  1361.     return (propertyName);
  1362.  
  1363.     SOM_CATCH_ALL
  1364.     SOM_ENDTRY
  1365.     return kODNULL;
  1366. }
  1367.  
  1368. //------------------------------------------------------------------------------
  1369. // CMStorageUnit: GetType
  1370. //------------------------------------------------------------------------------
  1371.  
  1372. SOM_Scope ODValueType  SOMLINK CMStorageUnitGetType(CMStorageUnit *somSelf, Environment *ev)
  1373. {
  1374.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1375.     CMStorageUnitMethodDebug("CMStorageUnit","GetType");
  1376.  
  1377.     SOM_TRY
  1378.  
  1379.     CMType            type;
  1380.     CMGlobalName    tmp;
  1381.     ODValueType    typeName = kODNULL;
  1382.  
  1383.     FailIfInvalidRefCount();
  1384.  
  1385.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1386.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1387.     
  1388.     CMContainer container = _fDraft->GetCMContainer(ev);
  1389.     ODSessionMustHaveCMAllocReserve(container);
  1390.  
  1391.     CMGetValueInfo(_fCurValue, kODNULL, kODNULL, kODNULL, &type, kODNULL);
  1392.     
  1393.     if (CMIsType(type)) {
  1394.         tmp = CMGetGlobalName(type);
  1395.         typeName = ODISOStrFromCStr(tmp);
  1396.     }
  1397.     ODSessionRestoreCMAllocReserve(container);
  1398.     
  1399.     return (typeName);
  1400.  
  1401.     SOM_CATCH_ALL
  1402.     SOM_ENDTRY
  1403.     return kODNULL;
  1404. }
  1405.  
  1406. //------------------------------------------------------------------------------
  1407. // CMStorageUnit: SetType
  1408. //------------------------------------------------------------------------------
  1409.  
  1410. SOM_Scope void  SOMLINK CMStorageUnitSetType(CMStorageUnit *somSelf, Environment *ev,
  1411.         ODValueType typeName)
  1412. {
  1413.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1414.     CMStorageUnitMethodDebug("CMStorageUnit","SetType");
  1415.  
  1416.     SOM_TRY
  1417.  
  1418.     CMContainer container = _fDraft->GetCMContainer(ev);
  1419.     CMType        type;
  1420.  
  1421.     FailIfInvalidRefCount();
  1422.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1423.     
  1424.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1425.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1426.         
  1427.     // CMContainer container = somSelf->GetCMContainer(ev);
  1428.     ODSessionMustHaveCMAllocReserve(container);
  1429.     
  1430.     type = CMRegisterType(container, (CMGlobalName) typeName);
  1431.     if (type != kODNULL)
  1432.         CMSetValueType(_fCurValue, type);
  1433.     else
  1434.         BREAK_AND_THROW(kODErrInvalidValueType);
  1435.  
  1436.     ODSessionRestoreCMAllocReserve(container);
  1437.  
  1438.     SOM_CATCH_ALL
  1439.     SOM_ENDTRY
  1440. }
  1441.  
  1442. //------------------------------------------------------------------------------
  1443. // CMStorageUnit: SetOffset
  1444. //------------------------------------------------------------------------------
  1445.  
  1446. SOM_Scope void  SOMLINK CMStorageUnitSetOffset(CMStorageUnit *somSelf, Environment *ev,
  1447.         ODULong offset)
  1448. {
  1449.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1450.     CMStorageUnitMethodDebug("CMStorageUnit","SetOffset");
  1451.  
  1452.     SOM_TRY
  1453.         FailIfInvalidRefCount();
  1454.         
  1455.         if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1456.             THROW(kODErrUnfocusedStorageUnit);
  1457.     
  1458.         _fOffset = offset;
  1459.     
  1460.     SOM_CATCH_ALL
  1461.     SOM_ENDTRY
  1462. }
  1463.  
  1464. SOM_Scope ODULong  SOMLINK CMStorageUnitGetOffset(CMStorageUnit *somSelf, Environment *ev)
  1465. {
  1466.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1467.     CMStorageUnitMethodDebug("CMStorageUnit","GetOffset");
  1468.  
  1469.     ODULong offset = 0;
  1470.     
  1471.     SOM_TRY
  1472.         FailIfInvalidRefCount();
  1473.         
  1474.         if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1475.             THROW(kODErrUnfocusedStorageUnit);
  1476.             
  1477.         offset = _fOffset;
  1478.         
  1479.     SOM_CATCH_ALL
  1480.     SOM_ENDTRY
  1481.     
  1482.     return offset;
  1483. }
  1484.  
  1485. //------------------------------------------------------------------------------
  1486. // CMStorageUnit: GetValue
  1487. //------------------------------------------------------------------------------
  1488.  
  1489. SOM_Scope ODULong  SOMLINK CMStorageUnitGetValue(CMStorageUnit *somSelf, Environment *ev,
  1490.         ODULong length,
  1491.         ODByteArray* value)
  1492. {
  1493.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1494.     CMStorageUnitMethodDebug("CMStorageUnit","GetValue");
  1495.  
  1496.     SOM_TRY
  1497.     
  1498.     FailIfIllegalByteArray(value);
  1499.     FailIfInvalidRefCount();
  1500.     
  1501.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1502.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1503.     
  1504.     if ((_fPromiseResolver != kODNULL) && (_fPromiseResolver->IsSettingPromise() == kODFalse))
  1505.         _fPromiseResolver->ResolvePromise(ev);
  1506.  
  1507.     value->_buffer = (octet*) ODNewPtr(length);
  1508.     value->_maximum = length;
  1509.     
  1510.     CMContainer container = _fDraft->GetCMContainer(ev);
  1511.     ODSessionMustHaveCMAllocReserve(container);
  1512.  
  1513.     value->_length = CMReadValueData(_fCurValue, (CMPtr) value->_buffer, _fOffset, length);
  1514.  
  1515.     ODSessionRestoreCMAllocReserve(container);
  1516.  
  1517.     _fOffset += value->_length;
  1518.  
  1519.     return value->_length;
  1520.  
  1521.     SOM_CATCH_ALL
  1522.     SOM_ENDTRY
  1523.     return 0;
  1524. }
  1525.  
  1526. //------------------------------------------------------------------------------
  1527. // CMStorageUnit: SetValue
  1528. //------------------------------------------------------------------------------
  1529.  
  1530. SOM_Scope void  SOMLINK CMStorageUnitSetValue(CMStorageUnit *somSelf, Environment *ev,
  1531.         ODByteArray* value)
  1532. {
  1533.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1534.     CMStorageUnitMethodDebug("CMStorageUnit","SetValue");
  1535.  
  1536.     SOM_TRY
  1537.     
  1538.     FailIfIllegalByteArray(value);
  1539.     FailIfInvalidRefCount();
  1540.     
  1541.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1542.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1543.  
  1544.     if ((_fPromiseResolver != kODNULL) && (_fPromiseResolver->IsSettingPromise() == kODFalse))
  1545.         _fPromiseResolver->ResolvePromise(ev);
  1546.  
  1547.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1548.     
  1549.     CMContainer container = _fDraft->GetCMContainer(ev);
  1550.     ODSessionMustHaveCMAllocReserve(container);
  1551.  
  1552.     CMWriteValueData(_fCurValue, (CMPtr) value->_buffer, _fOffset, value->_length);
  1553.  
  1554.     ODSessionRestoreCMAllocReserve(container);
  1555.  
  1556.     _fOffset += value->_length;
  1557.  
  1558.     SOM_CATCH_ALL
  1559.     SOM_ENDTRY
  1560. }
  1561.  
  1562. //------------------------------------------------------------------------------
  1563. // CMStorageUnit: InsertValue
  1564. //------------------------------------------------------------------------------
  1565.  
  1566. SOM_Scope void  SOMLINK CMStorageUnitInsertValue(CMStorageUnit *somSelf, Environment *ev,
  1567.         ODByteArray* value)
  1568. {
  1569.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1570.     CMStorageUnitMethodDebug("CMStorageUnit","InsertValue");
  1571.  
  1572.     SOM_TRY
  1573.     FailIfIllegalByteArray(value);
  1574.     FailIfInvalidRefCount();
  1575.     
  1576.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1577.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1578.  
  1579.     if ((_fPromiseResolver != kODNULL) && (_fPromiseResolver->IsSettingPromise() == kODFalse))
  1580.         _fPromiseResolver->ResolvePromise(ev);
  1581.  
  1582.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1583.  
  1584.     CMContainer container = _fDraft->GetCMContainer(ev);
  1585.     ODSessionMustHaveCMAllocReserve(container);
  1586.     
  1587.     CMInsertValueData(_fCurValue,(CMPtr)  value->_buffer, _fOffset, value->_length);
  1588.  
  1589.     ODSessionRestoreCMAllocReserve(container);
  1590.  
  1591.     _fOffset += value->_length;
  1592.  
  1593.     SOM_CATCH_ALL
  1594.     SOM_ENDTRY
  1595. }
  1596.  
  1597. //------------------------------------------------------------------------------
  1598. // CMStorageUnit: DeleteValue
  1599. //------------------------------------------------------------------------------
  1600.  
  1601. SOM_Scope void  SOMLINK CMStorageUnitDeleteValue(CMStorageUnit *somSelf, Environment *ev,
  1602.         ODULong length)
  1603. {
  1604.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1605.     CMStorageUnitMethodDebug("CMStorageUnit","DeleteValue");
  1606.  
  1607.     SOM_TRY
  1608.     FailIfInvalidRefCount();
  1609.     
  1610.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1611.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1612.  
  1613.     if ((_fPromiseResolver != kODNULL) && (_fPromiseResolver->IsSettingPromise() == kODFalse))
  1614.         _fPromiseResolver->ResolvePromise(ev);
  1615.  
  1616.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1617.  
  1618.     CMContainer container = _fDraft->GetCMContainer(ev);
  1619.     ODSessionMustHaveCMAllocReserve(container);
  1620.     
  1621.     CMDeleteValueData(_fCurValue, _fOffset, length);
  1622.  
  1623.     ODSessionRestoreCMAllocReserve(container);
  1624.  
  1625.     SOM_CATCH_ALL
  1626.     SOM_ENDTRY
  1627. }
  1628.  
  1629. //------------------------------------------------------------------------------
  1630. // CMStorageUnit: GetSize
  1631. //------------------------------------------------------------------------------
  1632.  
  1633. SOM_Scope ODULong  SOMLINK CMStorageUnitGetSize(CMStorageUnit *somSelf, Environment *ev)
  1634. {
  1635.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1636.     CMStorageUnitMethodDebug("CMStorageUnit","GetSize");
  1637.  
  1638.     SOM_TRY
  1639.     ODULong    size = 0;
  1640.     
  1641.     FailIfInvalidRefCount();
  1642.     somSelf->Internalize(ev);
  1643.  
  1644.     CMContainer container = _fDraft->GetCMContainer(ev);
  1645.     ODSessionMustHaveCMAllocReserve(container);
  1646.     // GetPropertySize() and GetObjectSize() call CM methods
  1647.         
  1648.     if (_fCurValue != kODNULL) {
  1649.         if ((_fPromiseResolver != kODNULL) && (_fPromiseResolver->IsSettingPromise() == kODFalse))
  1650.             _fPromiseResolver->ResolvePromise(ev);
  1651.         
  1652.         size = CMGetValueSize(_fCurValue);
  1653.     }
  1654.     else if (_fCurProperty != kODNULL)
  1655.         size = GetPropertySize(_fObject, _fCurProperty);
  1656.     else
  1657.         size = GetObjectSize(_fObject);
  1658.  
  1659.     ODSessionRestoreCMAllocReserve(container);
  1660.         
  1661.     return size;
  1662.  
  1663.     SOM_CATCH_ALL
  1664.     SOM_ENDTRY
  1665.     return 0;
  1666. }
  1667.  
  1668. //------------------------------------------------------------------------------
  1669. // CMStorageUnit: GetStrongStorageUnitRef
  1670. //------------------------------------------------------------------------------
  1671.  
  1672. SOM_Scope void  SOMLINK CMStorageUnitGetStrongStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  1673.         ODStorageUnitID embeddedSUID, ODStorageUnitRef ref)
  1674. {
  1675.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1676.     CMStorageUnitMethodDebug("CMStorageUnit","GetStrongStorageUnitRef");
  1677.  
  1678.     SOM_TRY
  1679.     
  1680.     somSelf->GetStorageUnitRef(ev, embeddedSUID, kODTrue, ref);
  1681.  
  1682.     SOM_CATCH_ALL
  1683.     SOM_ENDTRY
  1684. }
  1685.  
  1686. //------------------------------------------------------------------------------
  1687. // CMStorageUnit: GetWeakStorageUnitRef
  1688. //------------------------------------------------------------------------------
  1689.  
  1690. SOM_Scope void  SOMLINK CMStorageUnitGetWeakStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  1691.         ODStorageUnitID embeddedSUID, ODStorageUnitRef ref)
  1692. {
  1693.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1694.     CMStorageUnitMethodDebug("CMStorageUnit","GetWeakStorageUnitRef");
  1695.  
  1696.     SOM_TRY
  1697.     
  1698.     somSelf->GetStorageUnitRef(ev, embeddedSUID, kODFalse, ref);
  1699.  
  1700.     SOM_CATCH_ALL
  1701.     SOM_ENDTRY
  1702. }
  1703.  
  1704. //------------------------------------------------------------------------------
  1705. // CMStorageUnit: IsValidStorageUnitRef
  1706. //------------------------------------------------------------------------------
  1707.  
  1708. extern ODBoolean gODSuppressBentoFatalError; // defined in SessHdr.cpp
  1709.  
  1710. SOM_Scope ODBoolean  SOMLINK CMStorageUnitIsValidStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  1711.         ODStorageUnitRef ref)
  1712. {
  1713.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1714.     CMStorageUnitMethodDebug("CMStorageUnit","IsValidStorageUnitRef");
  1715.  
  1716.     ODBoolean oldSuppress = gODSuppressBentoFatalError;
  1717.     gODSuppressBentoFatalError = kODTrue;
  1718.  
  1719.     CMObject    object = kODNULL;
  1720.  
  1721.     SOM_TRY
  1722.         
  1723.     FailIfInvalidRefCount();
  1724.     
  1725.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1726.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1727.     
  1728.     ODVolatile(object);
  1729.     TRY
  1730.         CMContainer container = _fDraft->GetCMContainer(ev);
  1731.         ODSessionMustHaveCMAllocReserve(container);
  1732.         
  1733.         object = CMGetReferencedObject(_fCurValue, ref);
  1734.         if (object != kODNULL)
  1735.             CMReleaseObject(object);
  1736.             
  1737.         ODSessionRestoreCMAllocReserve(container);
  1738.     CATCH_ALL
  1739.         object = kODNULL;
  1740.     ENDTRY
  1741.     
  1742.     SOM_CATCH_ALL
  1743.         object=kODNULL;
  1744.     SOM_ENDTRY
  1745.  
  1746.     gODSuppressBentoFatalError = oldSuppress; // neutral
  1747.     return (object != kODNULL);
  1748. }
  1749.  
  1750. //------------------------------------------------------------------------------
  1751. // CMStorageUnit: IsStrongStorageUnitRef
  1752. //------------------------------------------------------------------------------
  1753.  
  1754. SOM_Scope ODBoolean  SOMLINK CMStorageUnitIsStrongStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  1755.         ODStorageUnitRef ref)
  1756. {
  1757.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1758.     CMStorageUnitMethodDebug("CMStorageUnit","IsStrongStorageUnitRef");
  1759.  
  1760.     return _fSURefKeeper->IsStrongSURef(ref);
  1761. }
  1762.  
  1763. //------------------------------------------------------------------------------
  1764. // CMStorageUnit: IsWeakStorageUnitRef
  1765. //------------------------------------------------------------------------------
  1766.  
  1767. SOM_Scope ODBoolean  SOMLINK CMStorageUnitIsWeakStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  1768.         ODStorageUnitRef ref)
  1769. {
  1770.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1771.     CMStorageUnitMethodDebug("CMStorageUnit","IsWeakStorageUnitRef");
  1772.  
  1773.     return _fSURefKeeper->IsWeakSURef(ref);
  1774. }
  1775.  
  1776. //------------------------------------------------------------------------------
  1777. // CMStorageUnit: RemoveStorageUnitRef
  1778. //------------------------------------------------------------------------------
  1779.  
  1780. SOM_Scope ODStorageUnit*  SOMLINK CMStorageUnitRemoveStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  1781.         ODStorageUnitRef ref)
  1782. {
  1783.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1784.     CMStorageUnitMethodDebug("CMStorageUnit","RemoveStorageUnitRef");
  1785.  
  1786.     SOM_TRY
  1787.     FailIfInvalidRefCount();
  1788.  
  1789.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1790.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1791.  
  1792.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1793.  
  1794.     CMContainer container = _fDraft->GetCMContainer(ev);
  1795.     ODSessionMustHaveCMAllocReserve(container);
  1796.         
  1797.     CMDeleteReference(_fCurValue, ref);
  1798.                     
  1799.     ODSessionRestoreCMAllocReserve(container);
  1800.     
  1801.     return somSelf;
  1802.  
  1803.     SOM_CATCH_ALL
  1804.     SOM_ENDTRY
  1805.     return somSelf;
  1806. }
  1807.  
  1808. //------------------------------------------------------------------------------
  1809. // CMStorageUnit: GetIDFromStorageUnitRef
  1810. //------------------------------------------------------------------------------
  1811.  
  1812. SOM_Scope ODStorageUnitID  SOMLINK CMStorageUnitGetIDFromStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  1813.         ODStorageUnitRef ref)
  1814. {
  1815.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1816.     CMStorageUnitMethodDebug("CMStorageUnit","GetIDFromStorageUnitRef");
  1817.  
  1818.     SOM_TRY
  1819.     FailIfInvalidRefCount();
  1820.     
  1821.     CMObject    object;
  1822.     
  1823.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1824.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1825.  
  1826.     CMContainer container = _fDraft->GetCMContainer(ev);
  1827.     ODSessionMustHaveCMAllocReserve(container);
  1828.     
  1829.     TRY
  1830.         object = CMGetReferencedObject(_fCurValue, ref);
  1831.     CATCH_ALL
  1832.         BREAK_AND_THROW(kODErrInvalidStorageUnitRef);
  1833.     ENDTRY
  1834.     
  1835.     if (object == kODNULL)
  1836.         BREAK_AND_THROW(kODErrInvalidStorageUnitRef);
  1837.         
  1838.     ODID    id = 0;
  1839.     IDList*    idList = ((CMDraft*) somSelf->GetDraft(ev))->GetIDList(ev);
  1840.     ASSERT(idList != kODNULL, kODErrInvalidIDList);
  1841.  
  1842.     if (idList->ObjectExists(object) != kODFalse) {
  1843.         id = idList->GetID(object);
  1844.         CMReleaseObject(object);
  1845.     }
  1846.     else {
  1847.         id = idList->Add(object);
  1848.     }
  1849.     ODSessionRestoreCMAllocReserve(container);
  1850.     
  1851.     return id;
  1852.  
  1853.     SOM_CATCH_ALL
  1854.     SOM_ENDTRY
  1855.     return 0;
  1856. }
  1857.  
  1858. //------------------------------------------------------------------------------
  1859. // CMStorageUnit: CreateStorageUnitRefIterator
  1860. //------------------------------------------------------------------------------
  1861.  
  1862. SOM_Scope ODStorageUnitRefIterator*  SOMLINK CMStorageUnitCreateStorageUnitRefIterator(CMStorageUnit *somSelf, Environment *ev)
  1863. {
  1864.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1865.     CMStorageUnitMethodDebug("CMStorageUnit","CrateStorageUnitRefIterator");
  1866.  
  1867.     SOM_TRY
  1868.     FailIfInvalidRefCount();
  1869.  
  1870.     CMStorageUnitRefIterator*    iter = NewCMStorageUnitRefIterator(somSelf->GetHeap(ev));
  1871.     iter->InitStorageUnitRefIterator(ev, somSelf);
  1872.  
  1873.     return iter;
  1874.  
  1875.     SOM_CATCH_ALL
  1876.     SOM_ENDTRY
  1877.     return kODNULL;
  1878. }
  1879.  
  1880. //------------------------------------------------------------------------------
  1881. // CMStorageUnit: GetGenerationNumber
  1882. //------------------------------------------------------------------------------
  1883.  
  1884. SOM_Scope ODULong  SOMLINK CMStorageUnitGetGenerationNumber(CMStorageUnit *somSelf, Environment *ev)
  1885. {
  1886.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1887.     CMStorageUnitMethodDebug("CMStorageUnit","GetGenerationNumber");
  1888.  
  1889.     SOM_TRY
  1890.     FailIfInvalidRefCount();
  1891.     
  1892.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1893.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1894.         
  1895.     ODULong    generation = 0;
  1896.  
  1897.     CMContainer container = _fDraft->GetCMContainer(ev);
  1898.     ODSessionMustHaveCMAllocReserve(container);
  1899.  
  1900.     CMGetValueInfo(_fCurValue, kODNULL, kODNULL, kODNULL, kODNULL, &generation);
  1901.     
  1902.     ODSessionRestoreCMAllocReserve(container);
  1903.  
  1904.     return generation;
  1905.  
  1906.     SOM_CATCH_ALL
  1907.     SOM_ENDTRY
  1908.     return 0;
  1909. }
  1910.  
  1911. //------------------------------------------------------------------------------
  1912. // CMStorageUnit: IncrementGenerationNumber
  1913. //------------------------------------------------------------------------------
  1914.  
  1915. SOM_Scope ODULong  SOMLINK CMStorageUnitIncrementGenerationNumber(CMStorageUnit *somSelf, Environment *ev)
  1916. {
  1917.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1918.     CMStorageUnitMethodDebug("CMStorageUnit","IncrementGenerationNumber");
  1919.  
  1920.     SOM_TRY
  1921.     FailIfInvalidRefCount();
  1922.     
  1923.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1924.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1925.  
  1926.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1927.  
  1928.     ODULong generation = somSelf->GetGenerationNumber(ev);
  1929.     generation++;
  1930.  
  1931.     CMContainer container = _fDraft->GetCMContainer(ev);
  1932.     ODSessionMustHaveCMAllocReserve(container);
  1933.  
  1934.     CMSetValueGeneration(_fCurValue, generation);
  1935.  
  1936.     ODSessionRestoreCMAllocReserve(container);
  1937.     
  1938.     return generation;
  1939.  
  1940.     SOM_CATCH_ALL
  1941.     SOM_ENDTRY
  1942.     return 0;
  1943. }
  1944.  
  1945. //------------------------------------------------------------------------------
  1946. // CMStorageUnit: GetSession
  1947. //------------------------------------------------------------------------------
  1948.  
  1949. SOM_Scope ODSession*     SOMLINK CMStorageUnitGetSession(CMStorageUnit *somSelf, Environment *ev)
  1950. {
  1951.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1952.     CMStorageUnitMethodDebug("CMStorageUnit","GetSession");
  1953.  
  1954.     SOM_TRY
  1955.  
  1956.     return (ODSession*) _fDraft->GetDocument(ev)->GetContainer(ev)->GetStorageSystem(ev)->GetSession(ev);
  1957.  
  1958.     SOM_CATCH_ALL
  1959.     SOM_ENDTRY
  1960.     return kODNULL;
  1961. }
  1962.  
  1963. //------------------------------------------------------------------------------
  1964. // CMStorageUnit: InitStorageUnit
  1965. //------------------------------------------------------------------------------
  1966.  
  1967. SOM_Scope void  SOMLINK CMStorageUnitInitStorageUnit(CMStorageUnit *somSelf, Environment *ev,
  1968.         ODDraft* draft,ODStorageUnitID suid)
  1969. {
  1970.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1971.     CMStorageUnitMethodDebug("CMStorageUnit","InitStorageUnit");
  1972.     
  1973.     SOM_TRY
  1974.             
  1975.     /* Moved from somInit. SOM itself sets fields to zero
  1976.     _fDraft = kODNULL;
  1977.     _fID = 0;
  1978.     _fObjectID = kODNULL;
  1979.     _fObject = kODNULL;
  1980.     _fCurProperty = kODIDAll;
  1981.     _fCurValueIndex = 0;
  1982.     _fCurValue = kODIDAll;
  1983.     _fCurValueType = 0;
  1984.     _fCurType = kODNULL;
  1985.     _fOffset = 0;
  1986.     _fHasPropertyLooped = kODFalse;
  1987.     _fHasValueLooped = kODFalse;
  1988.     
  1989.     _fCurrentKey = 0;
  1990.     _fLockCount = 0;
  1991.     
  1992.     _fSURefKeeper = kODNULL;
  1993.     
  1994. #ifdef USE_CLONEHELPER
  1995.     _fSUCloneHelper = kODNULL;
  1996. #endif
  1997.     
  1998.     _fHeap = kDefaultHeapID;
  1999.     
  2000.     _fModificationDate = 0;
  2001.     _fDirty = kODFalse;
  2002.     */
  2003.     _fCurProperty = kODIDAll;
  2004.     _fCurValue = kODIDAll;
  2005.     _fHeap = kDefaultHeapID;
  2006.     
  2007.     somSelf->InitRefCntObject(ev);
  2008.     
  2009.     
  2010.     if (draft != kODNULL) {
  2011.     
  2012.         _fDraft = (CMDraft*) draft;
  2013.         _fID = suid;
  2014.     
  2015.         IDList*    idList = kODNULL;
  2016.             
  2017.         idList = _fDraft->GetIDList(ev);
  2018.         ASSERT(idList != kODNULL, kODErrInvalidIDList);
  2019.     
  2020.         _fObject = (CMObject) idList->Get(_fID);
  2021.         if (_fObject == kODNULL)
  2022.             BREAK_AND_THROW(kODErrBentoInvalidObject);
  2023.         
  2024.         _fCMContainer = _fDraft->GetCMContainer(ev);
  2025.             
  2026.         _fObjectID = CMGetObjectID(_fObject);
  2027.         
  2028.         _fHeap = _fDraft->GetHeap(ev);
  2029.  
  2030.         _fPromiseResolver = new(_fHeap) PromiseResolver;
  2031.         _fPromiseResolver->InitPromiseResolver(somSelf);
  2032.         
  2033.         _fSURefKeeper = new(_fHeap) SURefKeeper(somSelf);
  2034.  
  2035. #ifdef USE_CLONEHELPER        
  2036.         _fSUCloneHelper = new(_fHeap) SUCloneHelper;
  2037. #endif
  2038.     }
  2039.     else
  2040.         THROW(kODErrIllegalNullDraftInput);
  2041.  
  2042.     SOM_CATCH_ALL
  2043.     SOM_ENDTRY
  2044. }
  2045.  
  2046.  
  2047. //------------------------------------------------------------------------------
  2048. // CMStorageUnit: ~CMStorageUnit
  2049. //------------------------------------------------------------------------------
  2050.  
  2051. SOM_Scope void  SOMLINK CMStorageUnitsomUninit(CMStorageUnit *somSelf)
  2052. {
  2053.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2054.     CMStorageUnitMethodDebug("CMStorageUnit","somUninit");
  2055.  
  2056.     delete _fPromiseResolver;
  2057.     delete _fSURefKeeper;
  2058.     
  2059. #ifdef USE_CLONEHELPER        
  2060.     delete _fSUCloneHelper;
  2061. #endif    
  2062.     
  2063.     CMStorageUnit_parents_somUninit(somSelf);
  2064.  
  2065. }
  2066.  
  2067. //------------------------------------------------------------------------------
  2068. // CMStorageUnit: CleanupAndFail
  2069. //------------------------------------------------------------------------------
  2070.  
  2071. SOM_Scope void  SOMLINK CMStorageUnitCleanupAndFail(CMStorageUnit *somSelf, Environment *ev,
  2072.         ODError err)
  2073. {
  2074.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2075.     CMStorageUnitMethodDebug("CMStorageUnit","CleanupAndFail");
  2076.  
  2077.     SOM_TRY
  2078.     
  2079. #ifdef ODDebug_ODStorageUnit
  2080.     somPrintf("Cleanup and fail: ID %x PID %x\n", somSelf->GetID(ev), _fObjectID);
  2081. #endif
  2082.  
  2083.     if (_fCurValue != kODNULL) {
  2084.         CMContainer container = _fDraft->GetCMContainer(ev);
  2085.         ODSessionMustHaveCMAllocReserve(container);
  2086.         
  2087.         CMReleaseValue(_fCurValue);
  2088.         
  2089.         ODSessionRestoreCMAllocReserve(container);
  2090.         
  2091.         _fCurValue = kODNULL;
  2092.     }
  2093.     if (err) {
  2094.         BREAK_AND_THROW(err);
  2095.     }
  2096.  
  2097.     SOM_CATCH_ALL
  2098.     SOM_ENDTRY
  2099. }
  2100.  
  2101. //------------------------------------------------------------------------------
  2102. // CMStorageUnit: Lock
  2103. //------------------------------------------------------------------------------
  2104.  
  2105. SOM_Scope ODStorageUnitKey  SOMLINK CMStorageUnitLock(CMStorageUnit *somSelf, Environment *ev,
  2106.         ODStorageUnitKey key)
  2107. {
  2108.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2109.     CMStorageUnitMethodDebug("CMStorageUnit","Lock");
  2110.     
  2111.     ODEnterCriticalSection();
  2112.     
  2113.     if (key == 0) {
  2114.         if (_fLockCount == 0) {
  2115.             _fLockCount = 1;
  2116.             _fCurrentKey++;
  2117.             key = _fCurrentKey;
  2118.         }
  2119.     }
  2120.     else {
  2121.         if ((_fCurrentKey != key) || (_fLockCount == 0))
  2122.             ODSetSOMException(ev,kODErrInvalidStorageUnitKey);
  2123.         else
  2124.             _fLockCount++;
  2125.     }
  2126.         
  2127.     ODExitCriticalSection();
  2128.     
  2129.     return key;
  2130. }
  2131.  
  2132. //------------------------------------------------------------------------------
  2133. // CMStorageUnit: Unlock
  2134. //------------------------------------------------------------------------------
  2135.  
  2136. SOM_Scope void  SOMLINK CMStorageUnitUnlock(CMStorageUnit *somSelf, Environment *ev,
  2137.         ODStorageUnitKey key)
  2138. {
  2139.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2140.     CMStorageUnitMethodDebug("CMStorageUnit","Unlock");
  2141.     
  2142.     ODEnterCriticalSection();
  2143.     
  2144.     if (_fCurrentKey != key)
  2145.         ODSetSOMException(ev,kODErrInvalidStorageUnitKey);
  2146.     
  2147.     else if (_fLockCount == 0)
  2148.         ODSetSOMException(ev,kODErrStorageUnitNotLocked);
  2149.     
  2150.     else
  2151.         --_fLockCount;
  2152.         
  2153.     ODExitCriticalSection();
  2154. }
  2155.  
  2156.  
  2157. //------------------------------------------------------------------------------
  2158. // CMStorageUnit: GetStorageUnitRef
  2159. //------------------------------------------------------------------------------
  2160.  
  2161. SOM_Scope void  SOMLINK CMStorageUnitGetStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  2162.         ODStorageUnitID embeddedSUID, ODBoolean strong, ODStorageUnitRef ref)
  2163. {
  2164.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2165.     CMStorageUnitMethodDebug("CMStorageUnit","GetStorageUnitRef");
  2166.  
  2167.     SOM_TRY
  2168.     FailIfInvalidRefCount();
  2169.  
  2170.     if (embeddedSUID == kODNULLID)
  2171.         THROW(kODErrIllegalNullStorageUnitInput);
  2172.         
  2173.     // Clear incoming reference
  2174.     _fSURefKeeper->InvalidateSURef(ref);
  2175.  
  2176.     CMReference            theReferenceData;    
  2177.     
  2178.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  2179.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  2180.         
  2181.     CMStorageUnit* embeddedSU = (CMStorageUnit*) somSelf->GetDraft(ev)->AcquireStorageUnit(ev, embeddedSUID);
  2182.     TempODStorageUnit tempSU = embeddedSU; // ensure it's released
  2183.     
  2184.     if (embeddedSU) {
  2185.         CMObject object = embeddedSU->GetObject(ev);
  2186.         if (object) {    
  2187.             CMContainer container = _fDraft->GetCMContainer(ev);
  2188.             ODSessionMustHaveCMAllocReserve(container);
  2189.             
  2190.             if (CMGetReferenceForObject(_fCurValue, object, theReferenceData) != kODNULL) {
  2191.                 // we already have this object in the reference, reuse the id            
  2192.                 ODBlockMove(theReferenceData, ref, sizeof(CMReference));
  2193.                 // if strong, value must be strong, else value must be weak
  2194.                 if ((strong != kODFalse) ? somSelf->IsWeakStorageUnitRef(ev, ref) : somSelf->IsStrongStorageUnitRef(ev, ref))
  2195.                     _fSURefKeeper->InvalidateSURef(ref);
  2196.             }
  2197.             
  2198.             if (somSelf->IsValidStorageUnitRef(ev, ref) == kODFalse) {
  2199.                 _fSURefKeeper->GetNextSURef(ref, strong);
  2200. //                ODBlockMove(ref, theReferenceData, sizeof(CMReference));
  2201.             }
  2202.             
  2203. //            CMSetReference(_fCurValue, embeddedSU->GetObject(ev), theReferenceData);
  2204.             CMSetReference(_fCurValue, object, ref);
  2205.  
  2206.             ODSessionRestoreCMAllocReserve(container);
  2207.         }
  2208.     }
  2209.  
  2210.     SOM_CATCH_ALL
  2211.     SOM_ENDTRY
  2212. }
  2213.  
  2214. //------------------------------------------------------------------------------
  2215. // CMStorageUnit: SetStorageUnitRef
  2216. //------------------------------------------------------------------------------
  2217.  
  2218. SOM_Scope void  SOMLINK CMStorageUnitSetStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  2219.         ODStorageUnitID embeddedSUID, ODStorageUnitRef ref)
  2220. {
  2221.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2222.     CMStorageUnitMethodDebug("CMStorageUnit","SetStorageUnitRef");
  2223.  
  2224.     SOM_TRY
  2225.     FailIfInvalidRefCount();
  2226.  
  2227.     CMReference            theReferenceData;
  2228.     
  2229.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  2230.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  2231.     
  2232.     if (embeddedSUID == 0)
  2233.         THROW(kODErrIllegalNullIDInput);
  2234.         
  2235.     CMStorageUnit* embeddedSU = (CMStorageUnit*) somSelf->GetDraft(ev)->AcquireStorageUnit(ev, embeddedSUID);
  2236.     TempODStorageUnit tempSU = embeddedSU;
  2237.     
  2238.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  2239.     
  2240.     ODBlockMove(ref, theReferenceData, sizeof(CMReference));
  2241.     
  2242.     if (_fSURefKeeper != kODNULL) {
  2243.         _fSURefKeeper->Reset(ref);
  2244.     }
  2245.     
  2246.     CMContainer container = _fDraft->GetCMContainer(ev);
  2247.     ODSessionMustHaveCMAllocReserve(container);
  2248.     
  2249.     CMSetReference(_fCurValue, embeddedSU->GetObject(ev), theReferenceData);
  2250.  
  2251.     ODSessionRestoreCMAllocReserve(container);
  2252.  
  2253.     SOM_CATCH_ALL
  2254.     SOM_ENDTRY
  2255. }
  2256.  
  2257. //------------------------------------------------------------------------------
  2258. // CMStorageUnit: GetHeap
  2259. //------------------------------------------------------------------------------
  2260.  
  2261. SOM_Scope ODMemoryHeapID  SOMLINK CMStorageUnitGetHeap(CMStorageUnit *somSelf, Environment *ev)
  2262. {
  2263.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2264.     CMStorageUnitMethodDebug("CMStorageUnit","GetHeap");
  2265.  
  2266.     return _fHeap;
  2267. }
  2268.  
  2269. //------------------------------------------------------------------------------
  2270. // CMStorageUnit: GetCMContainer
  2271. //------------------------------------------------------------------------------
  2272.  
  2273. SOM_Scope CMContainer  SOMLINK CMStorageUnitGetCMContainer(CMStorageUnit *somSelf, Environment *ev)
  2274. {
  2275.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2276.     CMStorageUnitMethodDebug("CMStorageUnit","GetCMContainer");
  2277.  
  2278.     SOM_TRY
  2279.  
  2280.     return _fDraft->GetCMContainer(ev);
  2281.  
  2282.     SOM_CATCH_ALL
  2283.     SOM_ENDTRY
  2284.     return kODNULL;
  2285. }
  2286.  
  2287. //------------------------------------------------------------------------------
  2288. // CMStorageUnit: SetChangedFromPrevFlag
  2289. //------------------------------------------------------------------------------
  2290.  
  2291. SOM_Scope void  SOMLINK CMStorageUnitSetChangedFromPrevFlag(CMStorageUnit *somSelf, Environment *ev,
  2292.         ODBoolean changed)
  2293. {
  2294.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2295.     CMStorageUnitMethodDebug("CMStorageUnit","SetChangedFromPrevFlag");
  2296.  
  2297.     SOM_TRY
  2298.  
  2299.     if (_fDraft != kODNULL)
  2300.         _fDraft->SetChangedFromPrevFlag(ev, changed);
  2301.  
  2302.     time((time_t *)(&_fModificationDate));
  2303.     
  2304.     _fDirty = kODTrue;
  2305.  
  2306.     SOM_CATCH_ALL
  2307.     SOM_ENDTRY
  2308. }
  2309.  
  2310. //------------------------------------------------------------------------------
  2311. // CMStorageUnit: GetObjectID
  2312. //------------------------------------------------------------------------------
  2313.  
  2314. SOM_Scope ODID  SOMLINK CMStorageUnitGetObjectID(CMStorageUnit *somSelf, Environment *ev)
  2315. {
  2316.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2317.     CMStorageUnitMethodDebug("CMStorageUnit","GetObjectID");
  2318.  
  2319.     return (ODID) _fObjectID;
  2320. }
  2321.  
  2322. //------------------------------------------------------------------------------
  2323. // GetPropertySize
  2324. //------------------------------------------------------------------------------
  2325.  
  2326. // Callers must call ODSessionMustHaveCMAllocReserve(container);
  2327.  
  2328. static ODULong GetPropertySize(CMObject object, CMProperty property)
  2329. {
  2330.     ODULong    size = 0;
  2331.     ODULong    numValues = CMCountValues(object, property, kODNULL);
  2332.     CMValue        curValue = kODNULL;
  2333.     
  2334.     for (ODULong i = 0; i < numValues; i++) {
  2335.         curValue = CMGetNextValue(object, property, curValue);
  2336.         if (curValue != kODNULL) {
  2337.             size += CMGetValueSize(curValue);
  2338.             CMReleaseValue(curValue);
  2339.         }
  2340.     }
  2341.     return size;
  2342. }
  2343.  
  2344. //------------------------------------------------------------------------------
  2345. // GetObjectSize
  2346. //------------------------------------------------------------------------------
  2347.  
  2348. // Callers must call ODSessionMustHaveCMAllocReserve(container);
  2349.  
  2350. static ODULong GetObjectSize(CMObject object)
  2351. {
  2352.     ODULong    size = 0;
  2353.     ODULong    numProperties = CMCountProperties(object, kODNULL);
  2354.     CMProperty    curProperty = kODNULL;
  2355.     
  2356.     for (ODULong i = 0; i < numProperties; i++) {
  2357.         curProperty = CMGetNextObjectProperty(object, curProperty);
  2358.         size += GetPropertySize(object, curProperty);
  2359.     }
  2360.     return size;
  2361. }
  2362.  
  2363. //------------------------------------------------------------------------------
  2364. // CMStorageUnit: GetCurValue
  2365. //------------------------------------------------------------------------------
  2366.  
  2367. SOM_Scope CMValue  SOMLINK CMStorageUnitGetCurValue(CMStorageUnit *somSelf, Environment *ev)
  2368. {
  2369.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2370.     CMStorageUnitMethodDebug("CMStorageUnit","GetCurValue");
  2371.  
  2372.     return _fCurValue;
  2373. }
  2374.  
  2375. //------------------------------------------------------------------------------
  2376. // CMStorageUnit: SetCurValue
  2377. //------------------------------------------------------------------------------
  2378. //
  2379. //SOM_Scope void  SOMLINK CMStorageUnitSetCurValue(CMStorageUnit *somSelf, Environment *ev, CMValue curValue)
  2380. //{
  2381. //    CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2382. //    CMStorageUnitMethodDebug("CMStorageUnit","SetCurValue");
  2383. //
  2384. //    _fCurValue = curValue;
  2385. //}
  2386.  
  2387. //------------------------------------------------------------------------------
  2388. // CMStorageUnit: GetObject
  2389. //------------------------------------------------------------------------------
  2390.  
  2391. SOM_Scope CMObject  SOMLINK CMStorageUnitGetObject(CMStorageUnit *somSelf, Environment *ev)
  2392. {
  2393.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2394.     CMStorageUnitMethodDebug("CMStorageUnit","GetCurValue");
  2395.  
  2396.     return _fObject;
  2397. }
  2398.  
  2399. //------------------------------------------------------------------------------
  2400. // CMStorageUnit: GetCurProperty
  2401. //------------------------------------------------------------------------------
  2402.  
  2403. SOM_Scope CMObject  SOMLINK CMStorageUnitGetCurProperty(CMStorageUnit *somSelf, Environment *ev)
  2404. {
  2405.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2406.     CMStorageUnitMethodDebug("CMStorageUnit","GetCurProperty");
  2407.  
  2408.     return _fCurProperty;
  2409. }
  2410.  
  2411. //------------------------------------------------------------------------------
  2412. // CMStorageUnit: GetCurType
  2413. //------------------------------------------------------------------------------
  2414.  
  2415. SOM_Scope CMType  SOMLINK CMStorageUnitGetCurType(CMStorageUnit *somSelf, Environment *ev)
  2416. {
  2417.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2418.     CMStorageUnitMethodDebug("CMStorageUnit","GetCurType");
  2419.  
  2420.     return _fCurType;
  2421. }
  2422.  
  2423. //------------------------------------------------------------------------------
  2424. // CMStorageUnit: SetCurType
  2425. //------------------------------------------------------------------------------
  2426.  
  2427. SOM_Scope void  SOMLINK CMStorageUnitSetCurType(CMStorageUnit *somSelf, Environment *ev, CMType curType)
  2428. {
  2429.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2430.     CMStorageUnitMethodDebug("CMStorageUnit","SetCurType");
  2431.  
  2432.     _fCurType = curType;
  2433. }
  2434.  
  2435. //------------------------------------------------------------------------------
  2436. // CMStorageUnit: IsPromiseValue
  2437. //------------------------------------------------------------------------------
  2438.  
  2439. SOM_Scope ODBoolean  SOMLINK CMStorageUnitIsPromiseValue(CMStorageUnit *somSelf, Environment *ev)
  2440. {
  2441.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2442.     CMStorageUnitMethodDebug("CMStorageUnit","CMStorageUnitIsPromiseValue");
  2443.  
  2444.     SOM_TRY
  2445.  
  2446.     if ( _fPromiseResolver )
  2447.         return _fPromiseResolver->IsPromiseValue(ev);
  2448.  
  2449.     SOM_CATCH_ALL
  2450.     SOM_ENDTRY
  2451.     return kODFalse;
  2452. }
  2453.  
  2454. //------------------------------------------------------------------------------
  2455. // CMStorageUnit: SetPromiseValue
  2456. //------------------------------------------------------------------------------
  2457.  
  2458. SOM_Scope void  SOMLINK CMStorageUnitSetPromiseValue(CMStorageUnit *somSelf, Environment *ev,
  2459.         ODValueType valueType,
  2460.         ODULong offset,
  2461.         ODByteArray* value,
  2462.         ODPart* sourcePart)
  2463. {
  2464.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2465.     CMStorageUnitMethodDebug("CMStorageUnit","CMStorageUnitSetPromiseValue");
  2466.  
  2467.     SOM_TRY
  2468.     FailIfIllegalByteArray(value);
  2469.     FailIfInvalidRefCount();
  2470.  
  2471.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL))
  2472.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  2473.     
  2474.     if (_fPromiseResolver != kODNULL) {
  2475.         _fPromiseResolver->SettingPromise();
  2476.  
  2477.         TRY
  2478. #if ODDebug_AddValue
  2479.             ODPropertyName propertyName = somSelf->GetProperty(ev);
  2480.             if (somSelf->Exists(ev, propertyName, valueType, 0) != kODFalse) {
  2481.                 somSelf->Focus(ev, propertyName, kODPosUndefined, valueType, 0, kODPosUndefined);
  2482.             }
  2483.             else
  2484.                 somSelf->AddValue(ev, valueType);
  2485.             ODDisposePtr(propertyName);
  2486. #else                
  2487.             somSelf->AddValue(ev, valueType);
  2488. #endif
  2489.             somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  2490.             
  2491.             somSelf->SetOffset(ev, offset);
  2492.             somSelf->SetValue(ev, value);
  2493.             
  2494.             _fPromiseResolver->SetSourcePart(ev, sourcePart);
  2495.             
  2496.             _fPromiseResolver->DoneSettingPromise();
  2497.         CATCH_ALL
  2498.             _fPromiseResolver->DoneSettingPromise();
  2499.             RERAISE;
  2500.         ENDTRY
  2501.     }
  2502.  
  2503.     SOM_CATCH_ALL
  2504.     SOM_ENDTRY
  2505. }
  2506.  
  2507. //------------------------------------------------------------------------------
  2508. // CMStorageUnit: GetPromiseValue
  2509. //------------------------------------------------------------------------------
  2510.  
  2511. SOM_Scope ODULong  SOMLINK CMStorageUnitGetPromiseValue(CMStorageUnit *somSelf, Environment *ev,
  2512.         ODValueType valueType,
  2513.         ODULong offset,
  2514.         ODULong length,
  2515.         ODByteArray* value,
  2516.         ODPart** sourcePart)
  2517. {
  2518.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2519.     CMStorageUnitMethodDebug("CMStorageUnit","CMStorageUnitGetPromiseValue");
  2520.  
  2521.     SOM_TRY
  2522.     FailIfIllegalByteArray(value);
  2523.     FailIfInvalidRefCount();
  2524.  
  2525.     somSelf->Focus(ev, kODNULL, kODPosSame, valueType, 0, kODPosSame);
  2526.     
  2527.     value->_buffer = (octet*) ODNewPtr(length);
  2528.     value->_maximum = length;
  2529.     value->_length = CMReadValueData(_fCurValue, (CMPtr) value->_buffer, offset, length);
  2530.     
  2531.     if ((_fPromiseResolver != kODNULL) && (sourcePart != kODNULL))
  2532.         *sourcePart = _fPromiseResolver->GetSourcePart(ev);
  2533.     
  2534.     return value->_length;
  2535.  
  2536.     SOM_CATCH_ALL
  2537.     SOM_ENDTRY
  2538.     return 0;
  2539. }
  2540.  
  2541. //------------------------------------------------------------------------------
  2542. // CMStorageUnit: ReleasePromisesInProperty
  2543. //------------------------------------------------------------------------------
  2544. //
  2545. // Releases all promises from all values current property, but leaves the promise 
  2546. // data in the value.  These values are meaningless, so this method should only be
  2547. // called when the values will never be used, such as prior to removing the property.
  2548.  
  2549. SOM_Scope void  SOMLINK CMStorageUnitReleasePromisesInProperty(CMStorageUnit *somSelf, Environment *ev)
  2550. {
  2551.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2552.     CMStorageUnitMethodDebug("CMStorageUnit","ReleasePromisesInProperty");
  2553.  
  2554.     SOM_TRY
  2555.     FailIfInvalidRefCount();
  2556.     
  2557.     if ( (_fPromiseResolver != kODNULL) && (_fPromiseResolver->GetPromiseCount() > 0) )
  2558.     {
  2559.         PreserveFocus originalFocus(ev, somSelf);
  2560.  
  2561.         // Focus to the current property
  2562.         somSelf->Focus(ev, (ODPropertyName) kODNULL,
  2563.                     kODPosSame,
  2564.                     kODTypeAll,
  2565.                     0,
  2566.                     kODPosUndefined);
  2567.         ODULong numValues = somSelf->CountValues(ev);    
  2568.         for (ODULong j = 0; j < numValues; j++)
  2569.         {
  2570.             somSelf->Focus(ev, (ODPropertyName) kODNULL,
  2571.                         kODPosSame,
  2572.                         kODTypeAll,
  2573.                         0,
  2574.                         kODPosNextSib);
  2575.             _fPromiseResolver->ClearPromise(ev);
  2576.             if (_fPromiseResolver->GetPromiseCount() == 0)
  2577.                 return;
  2578.         }
  2579.     }
  2580.  
  2581.     SOM_CATCH_ALL
  2582.     SOM_ENDTRY
  2583. }
  2584.  
  2585. //------------------------------------------------------------------------------
  2586. // CMStorageUnit: ReleaseAllPromises
  2587. //------------------------------------------------------------------------------
  2588. //
  2589. // Releases all promises from the storage unit, but leaves the promise data
  2590. // in the value.  These values are meaningless, so this method should only be
  2591. // called when the values will never be used, such as when the last reference
  2592. // to a storage unit is released. 
  2593.  
  2594. SOM_Scope void  SOMLINK CMStorageUnitReleaseAllPromises(CMStorageUnit *somSelf, Environment *ev)
  2595. {
  2596.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2597.     CMStorageUnitMethodDebug("CMStorageUnit","CMStorageUnitReleaseAllPromises");
  2598.  
  2599.     SOM_TRY
  2600.     FailIfInvalidRefCount();
  2601.     
  2602.     if (_fPromiseResolver && _fPromiseResolver->GetPromiseCount())
  2603.     {
  2604.         somSelf->Focus(ev,
  2605.                         (ODPropertyName) kODNULL, 
  2606.                         kODPosAll,
  2607.                         kODTypeAll,
  2608.                         0,
  2609.                         kODPosUndefined);
  2610.         ODULong numProperties = somSelf->CountProperties(ev);
  2611.         for (ODULong i = 0; i < numProperties; i++)
  2612.         {
  2613.             somSelf->Focus(ev,
  2614.                         (ODPropertyName) kODNULL,
  2615.                         kODPosNextSib,
  2616.                         kODTypeAll,
  2617.                         0,
  2618.                         kODPosUndefined);
  2619.             ODULong numValues = somSelf->CountValues(ev);    
  2620.             for (ODULong j = 0; j < numValues; j++)
  2621.             {
  2622.                 somSelf->Focus(ev,
  2623.                             (ODPropertyName)kODNULL,
  2624.                             kODPosSame,
  2625.                             kODTypeAll,
  2626.                             0,
  2627.                             kODPosNextSib);
  2628.                 _fPromiseResolver->ClearPromise(ev);
  2629.                 if (_fPromiseResolver->GetPromiseCount() == 0)
  2630.                     return;
  2631.             }
  2632.         }
  2633.     }
  2634.  
  2635.     SOM_CATCH_ALL
  2636.     SOM_ENDTRY
  2637. }
  2638.  
  2639. //------------------------------------------------------------------------------
  2640. // CMStorageUnit: ResolveAllPromises
  2641. //------------------------------------------------------------------------------
  2642.  
  2643. SOM_Scope void  SOMLINK CMStorageUnitResolveAllPromises(CMStorageUnit *somSelf, Environment *ev)
  2644. {
  2645.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2646.     CMStorageUnitMethodDebug("CMStorageUnit","CMStorageUnitResolveAllPromises");
  2647.  
  2648.     SOM_TRY
  2649.  
  2650.     if (_fPromiseResolver && _fPromiseResolver->GetPromiseCount())
  2651.     {
  2652.         PreserveFocus originalFocus(ev, somSelf);
  2653.  
  2654.         somSelf->Focus(ev, (ODPropertyName)kODNULL, 
  2655.                                 kODPosAll,
  2656.                                 kODTypeAll,
  2657.                                 0,
  2658.                                 kODPosUndefined);
  2659.         ODULong numProperties = somSelf->CountProperties(ev);
  2660.         for (ODULong i = 0; i < numProperties; i++)
  2661.         {
  2662.             somSelf->Focus(ev, (ODPropertyName)kODNULL,
  2663.                         kODPosNextSib,
  2664.                         kODTypeAll,
  2665.                         0,
  2666.                         kODPosUndefined);
  2667.             ODULong numValues = somSelf->CountValues(ev);    
  2668.             for (ODULong j = 0; j < numValues; j++)
  2669.             {
  2670.                 somSelf->Focus(ev, (ODPropertyName)kODNULL,
  2671.                             kODPosSame,
  2672.                             kODTypeAll,
  2673.                             0,
  2674.                             kODPosNextSib);
  2675.                 PreserveFocus* focus = new PreserveFocus(ev, somSelf);
  2676.                 _fPromiseResolver->ResolvePromise(ev);
  2677.                 delete focus;
  2678.                 numValues = somSelf->CountValues(ev);
  2679.                 numProperties = somSelf->CountProperties(ev);
  2680.                 if (_fPromiseResolver->GetPromiseCount() == 0)
  2681.                     return;
  2682.             }
  2683.         }
  2684.     }
  2685.  
  2686.     SOM_CATCH_ALL
  2687.     SOM_ENDTRY
  2688. }
  2689.  
  2690. //------------------------------------------------------------------------------
  2691. // CMStorageUnit: ClearAllPromises
  2692. //------------------------------------------------------------------------------
  2693. //
  2694. // Removes all promised values from the storage unit
  2695.  
  2696. SOM_Scope void  SOMLINK CMStorageUnitClearAllPromises(CMStorageUnit *somSelf, Environment *ev)
  2697. {
  2698.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2699.     CMStorageUnitMethodDebug("CMStorageUnit","ClearAllPromises");
  2700.  
  2701.     SOM_TRY
  2702.  
  2703.     if (_fPromiseResolver && _fPromiseResolver->GetPromiseCount())
  2704.     {
  2705.         // Focus to the entire storage unit
  2706.         somSelf->Focus(ev, (ODPropertyName)kODNULL, 
  2707.                                 kODPosAll,
  2708.                                 kODTypeAll,
  2709.                                 0,
  2710.                                 kODPosUndefined);
  2711.         ODULong numProperties = somSelf->CountProperties(ev);
  2712.         for (ODULong i = 0; i < numProperties; i++)
  2713.         {
  2714.             // Focus to the property
  2715.             somSelf->Focus(ev, (ODPropertyName) kODNULL,
  2716.                         kODPosNextSib,
  2717.                         kODTypeAll,
  2718.                         0,
  2719.                         kODPosUndefined);
  2720.  
  2721.             ODULong numValues = somSelf->CountValues(ev);    
  2722.  
  2723.             // Careful!  If a value is removed during iteration, the
  2724.             // index is unchanged but the limit is decremented!
  2725.             for (ODULong kindIndex = 1; kindIndex <= numValues;)
  2726.             {
  2727.                 somSelf->Focus(ev, (ODPropertyName) kODNULL, kODPosSame, kODNULL, kindIndex, kODPosUndefined);
  2728.                 if ( somSelf->IsPromiseValue(ev) )
  2729.                 {
  2730.                     somSelf->Remove(ev);
  2731.                     --numValues;
  2732.                     if (_fPromiseResolver->GetPromiseCount() == 0)
  2733.                         return;
  2734.                 }
  2735.                 else
  2736.                     ++kindIndex;
  2737.             }
  2738.             // Note that all values may have been removed from the property,
  2739.             // but the property remains.
  2740.         }
  2741.     }
  2742.  
  2743.     SOM_CATCH_ALL
  2744.     SOM_ENDTRY
  2745. }
  2746.  
  2747. //------------------------------------------------------------------------------
  2748. // NewODStorageUnitView
  2749. //------------------------------------------------------------------------------
  2750.  
  2751. static ODStorageUnitView* NewODStorageUnitView(ODMemoryHeapID heapID)
  2752. {
  2753.     SOMClass*    suViewClass = somNewClassReference(ODStorageUnitView);
  2754.     THROW_IF_NULL( suViewClass );
  2755.     ODULong        size = suViewClass->somGetInstanceSize();
  2756.     ODPtr        buffer = ODNewPtr(size, heapID);
  2757.     ODStorageUnitView*    suView = (ODStorageUnitView*) suViewClass->somRenew(buffer);
  2758.     somReleaseClassReference ( suViewClass );
  2759.     
  2760.     return suView;
  2761. }
  2762.  
  2763. //------------------------------------------------------------------------------
  2764. // NewODStorageUnitCursor
  2765. //------------------------------------------------------------------------------
  2766.  
  2767. static ODStorageUnitCursor* NewODStorageUnitCursor(ODMemoryHeapID heapID)
  2768. {
  2769.     SOMClass*    suCursorClass = somNewClassReference(ODStorageUnitCursor);
  2770.     THROW_IF_NULL( suCursorClass );
  2771.     ODULong        size = suCursorClass->somGetInstanceSize();
  2772.     ODPtr        buffer = ODNewPtr(size, heapID);
  2773.     ODStorageUnitCursor*    suCursor = (ODStorageUnitCursor*) suCursorClass->somRenew(buffer);
  2774.     somReleaseClassReference ( suCursorClass );
  2775.     
  2776.     return suCursor;
  2777. }
  2778.  
  2779. //------------------------------------------------------------------------------
  2780. // NewCMStorageUnitRefIterator
  2781. //------------------------------------------------------------------------------
  2782.  
  2783. static CMStorageUnitRefIterator* NewCMStorageUnitRefIterator(ODMemoryHeapID heapID)
  2784. {
  2785.     SOMClass*    refIterClass = somNewClassReference(CMStorageUnitRefIterator);
  2786.     THROW_IF_NULL( refIterClass );
  2787.     ODULong        size = refIterClass->somGetInstanceSize();
  2788.     ODPtr        buffer = ODNewPtr(size, heapID);
  2789.     CMStorageUnitRefIterator*    refIter = (CMStorageUnitRefIterator*) refIterClass->somRenew(buffer);
  2790.     somReleaseClassReference ( refIterClass );
  2791.     
  2792.     return refIter;
  2793. }
  2794.